You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 03:12:04