【问题标题】:Decorator Design Pattern - Not extending object behavior装饰器设计模式 - 不扩展对象行为
【发布时间】:2018-09-21 17:27:44
【问题描述】:

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

public class Computer {
    public Computer(){}

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

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

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

这里有两个组件类 Monitor 和 Disk 可以装饰计算机类。

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

下面是Start方法:

   void Start(){

        Computer computer = new Computer ();

        computer = new Disk (computer);
        computer = new Monitor (computer);

        print("You have a " + computer.Description () + ".");
    }

我的预期输出是:“您有一台计算机、一个监视器和一个磁盘。”

实际输出是:“你有一台电脑。”

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

【问题讨论】:

  • 您的ComponentDecorator 完全错误 - 最值得注意的是,您必须使用new 才能重新添加Description 的抽象版本。编译器警告您添加 new 会导致您在此处报告的问题。
  • new 不会连接对象,它会创建新对象并替换现有对象。
  • 在你的例子中你也必须装饰两次。恕我直言,装饰器模式可能不是您提供的任务的最佳解决方案。

标签: c# unity3d decorator


【解决方案1】:

您可以通过让您正在装饰的类和装饰器类具有相同的抽象(接口或抽象类)来实现装饰器。下面的代码显示了使用抽象类。我在这里添加的 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";
    }
}

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

【讨论】:

  • 所以澄清一下,如果我没有实现任何特定方法,那么我实际上可以完全删除 ComponentDecorator 类,只让 MonitorDiskComputer 继承。否则,创建一个抽象类Device 将需要我像这样实例化我的计算机:Device computer = new Computer(); 而不是Computer computer = new Computer(); Device 在您的示例中不是用作抽象装饰器类吗?也许我让自己更加困惑。
  • 是的,你是对的。在上面的示例中,您可以删除Device 类,并将Computer 类的Description() 方法设为virtual,并从Computer 类继承MonitorDisk 类。您可以根据需要调整设计模式。
【解决方案2】:

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

【讨论】:

  • 请不要在没有说明您所做的更改及其工作原理的情况下发布仅代码的答案。
猜你喜欢
  • 1970-01-01
  • 2013-02-19
  • 2010-10-05
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多