gpt4 book ai didi

c# - Decorator模式中抽象Decorator类的使用

转载 作者:太空狗 更新时间:2023-10-29 21:58:08 25 4
gpt4 key购买 nike

在 Decorator 设计模式中,我们有一个 ItemClass(例如 Coffee),然后是一个包含对 Coffee 的引用的 AbstractDecorator(例如 CoffeeDecorator)和 ConcreteDecorator(例如牛奶)。我的问题是,为什么我们需要 AbstractDecorator 类,为什么 Concrete Decorators 不直接继承自 Coffee 类?或者,如果我们已经想确保 ConcreteDecorators 具有对 ItemClass 的引用,为什么我们没有包含 ItemClass 属性的接口(interface)?使用这个 AbstractDecorator 我们只是禁用了一个选项,我们的 ConcreteDecorators 继承了其他一些类。提前谢谢!

最佳答案

我们使用抽象类从具体类中删除重复项。在装饰器模式中,您重复存储装饰对象实例并将调用传递给它。如果您不将此逻辑移动到基础(抽象)装饰器,那么您将需要在每个具体装饰器中实现它。


考虑以下饮料界面:

public interface IBeverage
{
decimal Price { get; }
string Description { get; }
}

由coffee实现:

public class Coffee : IBeverage
{
public decimal Price
{
get { return 3.5M; }
}

public string Description
{
get { return "Coffee"; }
}
}

现在您要为咖啡创建第一个装饰器。此时您不需要创建抽象装饰器。让我们的奶蜂免费。只需编写您需要的最简单的代码:

public class Milk : IBeverage
{
private readonly IBeverage _beverage;

public Milk(IBeverage beverage)
{
_beverage = beverage;
}

public decimal Price
{
get { return _beverage.Price; } // price not changed
}

public string Description
{
get { return _beverage.Description + " with milk"; }
}
}

现在你需要另一个装饰器。让它成为奶油:

public class Cream : IBeverage
{
private readonly IBeverage _beverage;

public Cream(IBeverage beverage)
{
_beverage = beverage;
}

public decimal Price
{
get { return _beverage.Price + 2M; }
}

public string Description
{
get { return _beverage.Description + " with cream"; }
}
}

您可以看到重复的代码。所以,是时候重构了。让我们将重复的代码移至抽象装饰器基类,该类负责保存对装饰饮料的引用并将调用传递给它:

public abstract class BeverageDecorator : IBeverage
{
private readonly IBeverage _beverage;

public BeverageDecorator(IBeverage beverage)
{
_beverage = beverage;
}

public virtual decimal Price
{
get { return _beverage.Price; }
}

public virtual string Description
{
get { return _beverage.Description; }
}
}

现在你可以只覆盖那些行为被你的装饰器改变的调用。牛奶装饰器看起来像:

public class Milk : BeverageDecorator
{
public Milk(IBeverage beverage)
: base(beverage)
{
}

public override string Description
{
get
{
return base.Description + " with milk";
}
}
}

更干净,是吗?这就是我们使用 base 装饰器的原因。

关于c# - Decorator模式中抽象Decorator类的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19446913/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com