7

这个线程,装饰器模式实现,有一个使用抽象类的装饰器实现。我不喜欢这样一个简单的事实,即 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
4

1 回答 1

4

基类和接口都经常用于建模 is-a 关系。即便是简单到IDisposable可以理解为“是一个生命周期可以手动控制的对象”、“一次性”的接口。更明显的区别在于是否允许基本实现或数据字段;以及他们组合多个层次结构的能力。

现在,当您实现任何模式时,您通常有足够的信息来查看是否需要数据字段。然而,随着软件的增长,您几乎无法排除将来需要在其他模式中包含相同的类。从这个角度来看,接口优于抽象类的普遍偏好为您提供了更长期的灵活性——只要您有选择。

根据装饰者的性质,您可以选择。组件通常没有预定义的嵌套顺序。如果他们这样做了,您将直接使用继承,而不是组件。所以你应该更喜欢接口来组成一个装饰器。

尽管如此,你原来的论点也是有效的。装饰器组件(特征)可以理解为 is-a 关系,如果你喜欢的话;但这不是看待它们的最自然的方式。

于 2013-04-18T20:50:21.827 回答