能否将Singleton等其他设计模式集成到现有Builder设计模式的C#项目中?
适配当前项目的设计模式及实现方案
你现有基于Builder模式实现的员工构建项目可以组合多种设计模式扩展能力,以下是匹配度最高的几种方案,包含可直接运行的改造代码:
1. 你提到的Singleton(单例)模式
你的EmployeeTestBuilder是无状态的构建工具类,不需要每次使用都实例化新对象,非常适合改造为单例,避免重复创建对象的开销:
public class EmployeeTestBuilder { // 单例实例 private static EmployeeTestBuilder _instance; // 锁保证多线程下单例安全 private static readonly object _lock = new object(); // 构造函数改为私有,禁止外部new private EmployeeTestBuilder() { _employee = new Employee(); } // 公开单例访问入口 public static EmployeeTestBuilder Instance { get { lock (_lock) { if (_instance == null) { _instance = new EmployeeTestBuilder(); } // 每次获取实例前重置内部Employee对象,避免上次构建的属性残留 _instance.Reset(); return _instance; } } } private Employee _employee; // 新增重置方法 private void Reset() { _employee = new Employee(); } public EmployeeTestBuilder WithName(string name) { _employee.Name = name; return this; } public EmployeeTestBuilder HasAge(int age) { _employee.BirthDate = new DateTime(DateTime.Now.Year - age, DateTime.Now.Month, DateTime.Now.Day); return this; } public EmployeeTestBuilder HasGrossSalaryOf(double salary) { _employee.GrossSalary = salary; return this; } public Employee Build() { return _employee; } }
改造后调用方式改为:
var employee = EmployeeTestBuilder.Instance .WithName("John") .HasAge(23) .HasGrossSalaryOf(2800) .Build();
2. Strategy(策略)模式
你现有CalculateNetSalary方法里的薪资计算逻辑是硬编码的,后续如果要新增个税梯度、专项扣除、员工类型补贴等规则时修改成本很高,用策略模式可以把薪资计算逻辑和Employee实体解耦,还可以和Builder模式配合,在构建员工时直接指定薪资计算规则:
首先定义薪资计算策略接口:
public interface INetSalaryCalculator { double Calculate(double grossSalary, int age); } // 30岁以下计算策略 public class Under30SalaryCalculator : INetSalaryCalculator { public double Calculate(double grossSalary, int age) { if (age < 18) throw new InvalidOperationException("Age less than 18"); return grossSalary * 0.8; } } // 30岁及以上计算策略 public class Over30SalaryCalculator : INetSalaryCalculator { public double Calculate(double grossSalary, int age) { if (age < 18) throw new InvalidOperationException("Age less than 18"); return grossSalary * 0.85; } }
改造Employee类和Builder:
public class Employee { public string Name { get; set; } public DateTime BirthDate { get; set; } public double GrossSalary { get; set; } // 注入薪资计算策略 public INetSalaryCalculator SalaryCalculator { get; set; } public double CalculateNetSalary() { var age = DateTime.Now.Year - BirthDate.Year; return SalaryCalculator.Calculate(GrossSalary, age); } public class EmployeeTestBuilder { // 原有Builder逻辑不变,新增指定策略方法 public EmployeeTestBuilder WithSalaryCalculator(INetSalaryCalculator calculator) { _employee.SalaryCalculator = calculator; return this; } } }
调用时可以灵活指定策略:
var employee = EmployeeTestBuilder.Instance .WithName("John") .HasAge(23) .HasGrossSalaryOf(2800) .WithSalaryCalculator(new Under30SalaryCalculator()) .Build();
3. Factory Method(工厂方法)模式
如果后续你需要生成不同类型的员工(比如全职员工、兼职员工、实习生),每种员工的属性校验规则、默认属性、薪资计算逻辑都不同,可以用工厂方法生成对应类型的Builder实例,不需要手动调整Builder参数。
内容的提问来源于stack exchange,提问作者Rakid Naomi
相关产品推荐
相关产品推荐

