在您的示例中,您确实显示了应用于给定产品的装饰器链,即:
var discountA = new BuyXGetYFreeDecorator(product, itemsToApplyTheDiscount, itemsYouGetFree);
var discountB = new FixedDiscountDecorator(discountA, discountPercentage);
那么问题是,有哪些模式可以用来改变product
由指定属性控制的状态,从上面的代码构建?使用您的示例并将我的范围限制为确定product
成本:
public interface IComponent
{
decimal GetCost { get; set; }
}
我会创建一个代表 IComponent 的产品类
public class Product
{
public IComponent Price { get; set; }
}
除了装饰器类之外,您可能还有一个“默认”实现
public class BasePrice : IComponent
{
private Decimal _cost;
public decimal GetCost //as a property maybe use Cost with get; set; in IComponent
{
get { return _cost; }
set { _cost = value; }
}
}
我喜欢你的两个装饰器类,它们使用 IoC 并从 IComponent 实现成本变化 (GetCost())。
到目前为止,我还没有真正添加任何东西,只是一个基本价格等级。我接下来可能做的是使用抽象类并将特定操作推迟到子类,如模板方法模式中所示。我的具体类将从这个基类继承。创建的具体类将取决于传递给工厂方法模式的操作类型,该类在下面称为 WarrantyProcessFactory。
您提到使用 app.config ...我喜欢枚举,我将使用它来指定要应用于的操作类型product
。因此,假设我希望采取与产品保修相关的行动,以便我可以基于此处理产品。
public enum WarrantyAction
{
RefundProduct = 0,
ReplaceProduct = 1
}
我将使用保修请求类来代表客户对缺陷产品的赔偿请求
public class WarrantyRequest
{
public WarrantyAction Action { get; set; }
public string PaymentTransactionId { get; set; }
public decimal PricePaid { get; set; }
public decimal PostageCost { get; set; }
public long ProductId { get; set; }
public decimal AmountToRefund { get; set; }
}
最后,我可以实现抽象模板方法,该方法将被代表保修操作枚举的具体类覆盖
public abstract class WarrantyProcessTemplate
{
protected abstract void GenerateWarrantyTransactionFor(WarrantyRequest warrantyRequest);
protected abstract void CalculateRefundFor(WarrantyRequest warrantyRequest);
public void Process(WarrantyRequest warrantyRequest)
{
GenerateWarrantyTransactionFor(warrantyRequest);
CalculateRefundFor(warrantyRequest);
}
}
类和前两个方法是抽象的,需要子类实现。第三个方法简单地调用两个抽象方法并将 WarrantyRequest 实体作为参数传递。
客户要求退款的情况
public class RefundWarrantyProcess : WarrantyProcessTemplate
{
protected override void GenerateWarrantyTransactionFor(WarrantyRequest warrantyRequest)
{
// Code to determine terms of the warranty and devalutionAmt...
}
protected override void CalculateRefundFor(WarrantyRequest warrantyRequest)
{
WarrantyRequest.AmountToRefund = warrantyRequest.PricePaid * devalutionAmt;
}
}
客户需要更换产品的情况
public class ReplaceWarrantyProcess : WarrantyProcessTemplate
{
protected override void GenerateWarrantyTransactionFor(WarrantyRequest warrantyRequest)
{
// Code to generate replacement order
}
protected override void CalculateRefundFor(WarrantyRequest warrantyRequest)
{
WarrantyRequest.AmountToRefund = warrantyRequest.PostageCost;
}
}
public static class WarrantyProcessFactory
{
public static WarrantyProcessTemplate CreateFrom(WarrantyAction warrantyAction)
{
switch (warrantyAction)
{
case (WarrantyAction.RefundProduct):
return new RefundWarrantyProcess();
case (WarrantyAction.ReplaceProduct):
return new ReplaceWarrantyProcess();
default:
throw new ApplicationException(
"No Process Template defined for Warranty Action of " +
warrantyAction.ToString());
}
}
}
我会考虑的另一种模式是策略方法模式。在这种情况下,Context 类将所有计算推迟到其抽象类或接口引用的“ConcreteStrategy”。我发现 Scott Millet 的书“专业 ASP.NET 设计模式”是一个有用的资源,并且经常返回它。
我愿意接受评论和批评。