这个线程Decorator pattern implementation有一个使用抽象类的装饰器的实现。我不喜欢它的简单事实,即CondimentDecorator不是那里给出的实施中的饮料。我会使用接口代替。对于is-a关系而言,抽象类不是更好吗?对于has-a关系,接口是否更好?
public interface IBeverage
{
// get a description of the beverage
String Description { get; }
// calculate cost of the beverage
double Cost { get; }
}
// HouseBlend coffee implements IBeverage
public class HouseBlend : IBeverage
{
private string description;
public String Description
{
get { return description; }
}
private double cost;
public double Cost
{
get { return cost; }
}
// Constructor
public HouseBlend() { description = "House Blend"; cost = 0.89; }
}
// DarkRoast coffee implements IBeverage
public class DarkRoast : IBeverage
{
private string description;
public String Description
{
get { return description; }
}
private double cost;
public double Cost
{
get { return cost; }
}
// Constructor
public DarkRoast() { description = "Dark Roast"; cost = 1.10; }
}
// Mocha is a Decorator
public class Mocha
{
// Mocha has-a Beverage
private IBeverage m_beverage;
private string description;
public String Description
{
get { return description; }
}
private public double Cost
{
get { return cost; }
}
// Constructor binds the object passed to member var
public Mocha(IBeverage beverage)
{
m_beverage = beverage; // not necessary for the purpose of this example
description = m_beverage.Description + ", Mocha";
cost = 0.20 + m_beverage.Cost;
}
}
Use like this:
Mocha mhb = new Mocha(new HouseBlend()); // house blend with mocha flavor
答案 0 :(得分:4)
基础clases和接口经常用于建模is-a关系。即使像IDisposable
这样简单的界面也可以理解为“是一个具有手动控制生命周期的对象”,即“一次性”。更切实的区别在于是否允许基本实现或数据字段;以及他们组合多个层次结构的能力。
现在,当您实现任何模式时,通常会有足够的信息来查看是否需要数据字段。但是,随着软件的发展,您几乎无法排除未来需要在其他模式中使用相同的类。从这个角度来看,接口对抽象类的一般偏好为您提供了更长期的灵活性 - 只要您有选择。
根据装饰者的性质,你可以选择。组件通常没有预定义的嵌套方式。如果他们这样做,你将直接使用继承,而不是组件。所以你应该更喜欢使用接口来组成一个装饰器。
所有这一切,你的原始论点也是有效的。装饰器组件(功能)可以理解为 - 如果你喜欢的话,就是一种关系;但这并不是看待它们最自然的方式。