C#多构造器参数使用Builder设计模式重构

创建一个使用Builder模式的高级示例,展示如何优雅地处理多构造器参数的情况

// 产品类 - 一个复杂的订单系统
public class Order
{
    // 必需参数
    public string OrderId { get; private set; }
    public string CustomerName { get; private set; }
    
    // 可选参数
    public string ShippingAddress { get; private set; }
    public string PaymentMethod { get; private set; }
    public decimal? Discount { get; private set; }
    public bool IsExpressDelivery { get; private set; }
    public DateTime? DeliveryDate { get; private set; }
    public string SpecialInstructions { get; private set; }
    public List<string> OrderItems { get; private set; }
    public string CouponCode { get; private set; }

    // 私有构造函数,只能通过Builder创建实例
    private Order() 
    {
        OrderItems = new List<string>();
    }

    // 静态Builder类
    public class OrderBuilder
    {
        private readonly Order _order;

        // 构造器要求必填参数
        public OrderBuilder(string orderId, string customerName)
        {
            _order = new Order
            {
                OrderId = orderId,
                CustomerName = customerName
            };
        }

        // 流式接口方法
        public OrderBuilder WithShippingAddress(string address)
        {
            _order.ShippingAddress = address;
            return this;
        }

        public OrderBuilder WithPaymentMethod(string paymentMethod)
        {
            _order.PaymentMethod = paymentMethod;
            return this;
        }

        public OrderBuilder WithDiscount(decimal discount)
        {
            if (discount < 0 || discount > 100)
                throw new ArgumentException("Discount must be between 0 and 100");
            _order.Discount = discount;
            return this;
        }

        public OrderBuilder WithExpressDelivery(bool isExpress = true)
        {
            _order.IsExpressDelivery = isExpress;
            return this;
        }

        public OrderBuilder WithDeliveryDate(DateTime deliveryDate)
        {
            if (deliveryDate < DateTime.Now)
                throw new ArgumentException("Delivery date cannot be in the past");
            _order.DeliveryDate = deliveryDate;
            return this;
        }

        public OrderBuilder WithSpecialInstructions(string instructions)
        {
            _order.SpecialInstructions = instructions;
            return this;
        }

        public OrderBuilder AddOrderItem(string item)
        {
            _order.OrderItems.Add(item);
            return this;
        }

        public OrderBuilder AddOrderItems(IEnumerable<string> items)
        {
            _order.OrderItems.AddRange(items);
            return this;
        }

        public OrderBuilder WithCouponCode(string couponCode)
        {
            _order.CouponCode = couponCode;
            return this;
        }

        // 构建方法
        public Order Build()
        {
            ValidateOrder(_order);
            return _order;
        }

        // 验证逻辑
        private void ValidateOrder(Order order)
        {
            var errors = new List<string>();

            if (string.IsNullOrEmpty(order.OrderId))
                errors.Add("OrderId is required");
            if (string.IsNullOrEmpty(order.CustomerName))
                errors.Add("CustomerName is required");
            if (order.IsExpressDelivery && !order.DeliveryDate.HasValue)
                errors.Add("Delivery date is required for express delivery");
            if (!string.IsNullOrEmpty(order.CouponCode) && !order.Discount.HasValue)
                errors.Add("Discount must be specified when using coupon code");

            if (errors.Any())
                throw new InvalidOperationException(
                    $"Order validation failed: {string.Join(", ", errors)}");
        }
    }
}

// 示例用法及高级特性
public class OrderService
{
    public void DemoBuilderPattern()
    {
        // 基本用法
        var simpleOrder = new Order.OrderBuilder("ORD001", "John Doe")
            .WithShippingAddress("123 Main St")
            .WithPaymentMethod("Credit Card")
            .Build();

        // 复杂用法展示
        var complexOrder = new Order.OrderBuilder("ORD002", "Jane Smith")
            .WithShippingAddress("456 Oak Ave")
            .WithPaymentMethod("PayPal")
            .WithDiscount(15.5m)
            .WithExpressDelivery()
            .WithDeliveryDate(DateTime.Now.AddDays(2))
            .WithSpecialInstructions("Please leave at the front door")
            .AddOrderItem("Item 1")
            .AddOrderItem("Item 2")
            .AddOrderItems(new[] { "Item 3", "Item 4" })
            .WithCouponCode("SUMMER2024")
            .Build();

        // 链式调用的灵活性
        var customOrder = new Order.OrderBuilder("ORD003", "Bob Wilson");
        
        // 条件性添加属性
        if (DateTime.Now.Hour < 12)
        {
            customOrder.WithExpressDelivery()
                      .WithDeliveryDate(DateTime.Now.AddDays(1));
        }

        if (IsVipCustomer("Bob Wilson"))
        {
            customOrder.WithDiscount(20m)
                      .WithCouponCode("VIP2024");
        }

        var finalOrder = customOrder.Build();
    }

    private bool IsVipCustomer(string customerName)
    {
        // 示例方法
        return true;
    }
}

这个Builder模式的实现包含了许多高级特性:

  1. 必需参数验证

    • 通过构造函数强制要求必需参数(OrderId和CustomerName)
    • Build()方法中包含详细的验证逻辑
  2. 流式接口

    • 所有设置方法都返回builder实例,支持链式调用
    • 方法命名清晰直观,使用With前缀表示属性设置
  3. 集合处理

    • 提供了单个和批量添加订单项的方法
    • 支持IEnumerable接口,提高了灵活性
  4. 业务规则验证

    • 折扣范围检查
    • 送货日期有效性验证
    • 快递订单必须指定送货日期
    • 使用优惠券时必须指定折扣
  5. 灵活的构建过程

    • 支持条件性添加属性
    • 可以根据业务逻辑动态构建对象
  6. 封装性

    • Order类的构造函数是私有的,确保只能通过Builder创建实例
    • 属性都是私有设置的,保证对象不可变性

这种实现方式特别适合:

  • 构造参数较多的复杂对象
  • 需要强制验证的场景
  • 需要灵活构建过程的情况
  • 对象创建需要遵循特定业务规则的情况

你可以根据具体需求调整验证规则和添加更多的业务逻辑。需要我详细解释某个具体部分吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值