简体   繁体   English

C#装饰器 - 接口或抽象类?

[英]C# Decorators - Interfaces or Abstract Classes?

This thread, Decorator pattern implementation , has an implementation of a decorator using abstract classes. 这个线程, Decorator模式实现 ,有一个使用抽象类的装饰器的实现。 I don't like it for the simple fact that a CondimentDecorator is NOT a Beverage in the implementation given there. 我不喜欢它的简单事实,即CondimentDecorator不是那里给出的实施中的饮料。 I'd use interfaces instead. 我会使用接口代替。 Aren't abstract classes better for is-a relationships, and interfaces better for has-a relationships? 对于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

Both base clases and interfaces are frequently used to model is-a relationships. 基础clases和接口经常用于建模is-a关系。 Even an interface as simple as IDisposable can be understood as "is an object with a manually controlled lifecycle", a "disposable". 甚至像IDisposable这样简单的界面也可以理解为“是具有手动控制生命周期的对象”,“一次性”。 The more tangible differences are in whether base implementation or data fields are allowed; 更切实的区别在于是否允许基本实现或数据字段; and in their ability to combine multiple hierarchies. 以及他们组合多个层次结构的能力。

Now, when you are implementing any pattern, you usually have enough information to see whether you need data fields or not. 现在,当您实现任何模式时,通常都有足够的信息来查看是否需要数据字段。 However, you will hardly ever be able to rule out a future need to involve the same classes in additional patterns as your software grows. 但是,随着软件的发展,您几乎无法排除未来需要在其他模式中使用相同的类。 From that perspective, a general preference of interfaces over abstract classes gives you more long term flexibility - whenever you have a choice. 从这个角度来看,接口对抽象类的一般偏好为您提供了更长期的灵活性 - 只要您有选择。

By the nature of a Decorator, you have a choice. 根据装饰者的性质,您可以选择。 The components typically do not have a predefined order of how they should nest. 组件通常没有预定义的嵌套方式。 If they did, you would use inheritance directly, instead of components. 如果他们这样做,你将直接使用继承,而不是组件。 So you should prefer interfaces to compose a Decorator. 所以你应该更喜欢接口来组成一个Decorator。

All that said, your original argument is valid as well. 总而言之,你的原始论点也是有效的。 Decorator components (features) can be understood as is-a relationships if you like; 装饰器组件(功能)可以理解为 - 如果你喜欢的话,就是一种关系; but it is not the most natural way of looking at them. 但它不是最自然的看待它们的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM