我正在学习更多关于设计模式的知识,我正在尝试实现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描述方法一样?如何修改它以获得预期的输出?
答案 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();
}
}