C# 装饰器设计模式-不扩展对象行为
我正在学习更多关于设计模式的知识,我正在尝试实现Decorator模式。我想扩展一个计算机对象,在每个新组件的描述末尾添加一个字符串。这是Unity/C改编自《傻瓜设计模式》一书中的java示例C# 装饰器设计模式-不扩展对象行为,c#,unity3d,decorator,C#,Unity3d,Decorator,我正在学习更多关于设计模式的知识,我正在尝试实现Decorator模式。我想扩展一个计算机对象,在每个新组件的描述末尾添加一个字符串。这是Unity/C改编自《傻瓜设计模式》一书中的java示例 public class Computer { public Computer(){} public string Description(){ return "Computer"; } } 这是每个组件将从中继承的装饰器组件: public abstract
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";
}
}
以下是启动方法:
void Start(){
Computer computer = new Computer ();
computer = new Disk (computer);
computer = new Monitor (computer);
print("You have a " + computer.Description () + ".");
}
我的预期结果是:“你有一台电脑、一台显示器和一张磁盘。”
实际输出是:“你有一台电脑。”
计算机现在不应该像调用监视器描述方法一样调用描述方法吗?如何对其进行修改以获得预期的输出?您的实施缺少要点。有同样好的解释和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();
}
}
您可以通过使您正在装饰的类和装饰器类具有相同的抽象(接口或抽象类)来实现装饰器。下面的代码显示如何使用抽象类。我在这里添加的设备类是decorator类和decorating类的抽象
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";
}
}
您不需要decorator类的抽象,除非您希望所有的decorator实现任何特定的方法。您的
组件decorator
都是错误的-最值得注意的是,您必须使用new
来重新添加Description
的抽象版本。编译器警告您,添加new
会导致您在此处报告的问题。new
不会连接对象,它会创建新对象并替换现有对象。您还必须在示例中修饰两次。我认为装饰模式可能不是您提供的任务的最佳解决方案。请不要只发布代码答案,而不解释您更改了什么以及它是如何工作的。因此,为了澄清,如果我没有实现任何特定的方法,那么我实际上可以删除ComponentDecorator
类,只需要监视器
和磁盘
从计算机
继承。否则,创建抽象类Device
需要实例化我的计算机,如:Device computer=new computer()代码>而不仅仅是计算机=新计算机()在您的示例中,Device
不是作为抽象装饰器类吗?也许我更糊涂了。是的,你是对的。在上面的示例中,您可以删除设备
类,并将计算机
类的Description()
方法设置为虚拟
,并从计算机
类继承监视器
和磁盘
类。您可以根据需要调整设计模式。