装饰器设计模式 - 不扩展对象行为



我正在学习更多关于设计模式的知识,我正在尝试实现装饰器模式。我想扩展一个计算机对象,在每个新组件的描述末尾添加一个字符串。这是 Unity/C# 改编自《傻瓜设计模式》一书中的 Java 示例。

public class Computer {
    public Computer(){}
    public string Description(){
        return "Computer";
    }
}

这是每个组件将继承自的装饰器组件:

public abstract class ComponentDecorator : Computer {
    new public abstract string Description();
}

下面是两个组件类监视器和磁盘,它们可以装饰计算机类。

public class Monitor : ComponentDecorator {
    Computer computer;
    public Monitor(Computer c){
        this.computer = c;
    }
    public override string Description(){
        return computer.Description () + " and a Monitor";
    }
}
public class Disk : ComponentDecorator {
    Computer computer;
    public Disk(Computer c){
        this.computer = c;
    }
    public override string Description(){
        return computer.Description () + " and a Disk";
    }
}

下面是启动方法:

   void Start(){
        Computer computer = new Computer ();
        computer = new Disk (computer);
        computer = new Monitor (computer);
        print("You have a " + computer.Description () + ".");
    }

我的预期输出是:"你有一台计算机、一台显示器和一个磁盘。

实际输出为:"你有一台计算机。

计算机现在不应该像调用监视器描述方法一样调用描述方法吗?如何修改它以获得预期的输出?

您可以通过使要修饰的类和装饰器类具有相同的抽象(接口或抽象类(来实现装饰器。下面的代码演示如何使用抽象类。我在此处添加的 Device 类是装饰器类和装饰类的抽象。

public abstract class Device
{
    public abstract string Description();
}

public class Computer : Device
{
    public Computer() { }
    public override string Description()
    {
        return "Computer";
    }
}

public class Monitor : Device
{
    Device device;
    public Monitor(Device c)
    {            this.device = c;
    }
    public override string Description()
    {
        return device.Description() + " and a Monitor";
    }
}
public class Disk : Device
{
    Device device;
    public Disk(Device c)
    {
        this.device = c;
    }
    public override string Description()
    {
        return device.Description() + " and a Disk";
    }
}

不需要装饰器类的抽象,除非你希望所有的装饰器实现任何特定的方法。

你的暗示有缺失的点。 http://www.dofactory.com/net/decorator-design-pattern 有同样好的解释和UML图。我像这样实现你的案例:

public abstract class ComputerParts
{
    public abstract string Description();
}
public class Computer : ComputerParts
{
    public Computer()
        {
        }
    public override string Description()
        {
            return "Computer";
        }
}
public abstract class ComponentDecorator : ComputerParts
{
    public abstract void ExtraMethod();
}
public class Disk : ComponentDecorator
{
    ComputerParts computerParts;
    public Disk(ComputerParts c)
        {
            this.computerParts = c;
        }
    public override string Description()
        {
            return computerParts.Description() + " and a Disk";
        }
    public override void ExtraMethod()
        {
            throw new NotImplementedException();
        }
}
public class Monitor : ComponentDecorator
{
    ComputerParts computerParts;
    public Monitor(ComputerParts c)
        {
            this.computerParts = c;
        }
    public override string Description()
        {
            return computerParts.Description() + " and a Monitor";
        }
    public override void ExtraMethod()
        {
            throw new NotImplementedException();
        }
}

最新更新