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

时间:2018-04-11 17:57:52

标签: c# unity3d decorator

我正在学习更多关于设计模式的知识,我正在尝试实现Decorator模式。我想扩展一个计算机对象,以便为每个新组件的描述末尾添加一个字符串。这是来自Design Patterns For Dummies书中的java示例的Unity / C#改编。

StaggeredGridView

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

public class Computer {
    public Computer(){}

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

以下是可以装饰计算机类的两个组件类Monitor和Disk。

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

以下是Start方法:

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";
    }
}

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

实际输出为:"您有一台电脑。"

现在计算机是否应该调用描述方法,就好像它是Monitor描述方法一样?如何修改它以获得预期的输出?

2 个答案:

答案 0 :(得分:2)

您可以通过让您正在装饰的类和装饰器类具有相同的抽象(接口或抽象类)来实现装饰器。下面的代码显示了使用抽象类。我在这里添加的Device类是decorator类和装饰类的抽象。

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";
    }
}

除非您希望所有装饰器都实现任何特定方法,否则您不需要对装饰器类进行抽象。

答案 1 :(得分:0)

您的实施有缺失点。 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();
        }
}