创建一个使用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模式的实现包含了许多高级特性:
-
必需参数验证:
- 通过构造函数强制要求必需参数(OrderId和CustomerName)
- Build()方法中包含详细的验证逻辑
-
流式接口:
- 所有设置方法都返回builder实例,支持链式调用
- 方法命名清晰直观,使用With前缀表示属性设置
-
集合处理:
- 提供了单个和批量添加订单项的方法
- 支持IEnumerable接口,提高了灵活性
-
业务规则验证:
- 折扣范围检查
- 送货日期有效性验证
- 快递订单必须指定送货日期
- 使用优惠券时必须指定折扣
-
灵活的构建过程:
- 支持条件性添加属性
- 可以根据业务逻辑动态构建对象
-
封装性:
- Order类的构造函数是私有的,确保只能通过Builder创建实例
- 属性都是私有设置的,保证对象不可变性
这种实现方式特别适合:
- 构造参数较多的复杂对象
- 需要强制验证的场景
- 需要灵活构建过程的情况
- 对象创建需要遵循特定业务规则的情况
你可以根据具体需求调整验证规则和添加更多的业务逻辑。需要我详细解释某个具体部分吗?

2917

被折叠的 条评论
为什么被折叠?



