我正在阅读装饰设计模式,无法理解一些事情 我有四个班级
public class Computer
{
public Computer()
{
}
public String description()
{
return "computer";
}
}
public abstract class ComponentDecorator extends Computer
{
public abstract String description();
}
public class Disk extends ComponentDecorator
{
Computer computer;
public Disk(Computer c)
{
computer = c;
}
public String description()
{
return computer.description() + " and a disk";
}
}
public class Monitor extends ComponentDecorator
{
Computer computer;
public Monitor(Computer c)
{
computer = c;
}
public String description()
{
return computer.description() + " and a monitor";
}
}
这是最终的测试类
public class Test
{
public static void main(String args[])
{
Computer computer = new Computer();
computer = new Disk(computer);
computer = new Monitor(computer);
computer = new CD(computer);
computer = new CD(computer);
System.out.println("You're getting a " + computer.description()
+ ".");
}
}
现在最后的输出是
computer and a disk and a monitor and a cd
令我困惑的是
1)为什么他采用了相同的对象名计算机,为什么不使用计算机1,计算机2)如果计算机obj相同则不意味着只有最后一个声明才有效而其他声明将被覆盖
我认为输出应该是computer and a CD
答案 0 :(得分:3)
这就是装饰器模式的作用。它用新属性“装饰”现有对象。
因此,您拥有的最终装饰对象是CD
对象,其私有成员computer
的类型为Computer
。但是这个computer
对象是Monitor
创建的对象,它还有一个名为computer
的私有成员。在您到达原始Computer
对象之前,此模式会重复出现。
现在,当您致电description()
时,您正在执行computer.description()
以及当前班级的一些文字。第一个调用会一直向上链接,直到您到达第一个计算机对象,该对象从computer
对象打印and a disk
,然后Disk
,然后从and a monitor
对象打印Monitor
来自and a CD
对象的CD
对象,最后是computer
。
你每次都可以使用一个新变量,并将该对象传递给每个连续的对象。这取决于你在寻找什么。在这里,您只是重复使用变量。
此ASCII艺术可能有助于您了解对象之间的关系。每个框中的 CD Monitor Disk Computer
__________ ___________ ___________ ___________
| computer-|---|->computer-|---|->computer-|---|->computer |
|__________| |___________| |___________| |___________|
指的是每个类的私有成员。
description()
现在,在以下ASCII艺术中,您会看到每个“框”打印的内容。顶部的箭头显示了每个description()
方法中return语句的执行顺序。方框之间的箭头显示了每个 order of print
<-------------------------------------------------------------------+
CD Monitor Disk Computer |
|
call from Main __________ _______________ ____________ __________ |
----------------> | and a cd |-->| and a monitor |-->| and a disk |-->| computer |----+
|__________| |_______________| |____________| |__________|
方法的调用顺序
{{1}}
希望我糟糕的ASCII艺术有助于:)
答案 1 :(得分:1)
装饰器模式的要点是在现有行为之上层叠新行为。在这种情况下,重点是通过添加新外围设备来构建计算机。可能让您感到困惑的一件事是,类的名称并不特别适合行为。例如,我可能会将它命名为DiskAddition
(甚至是DiskDecorator
,一旦理解了模式),而不仅仅是Disk
,因为意图是您带一台计算机并添加磁盘到它,而不是你从计算机创建一个新磁盘。为结果对象重用相同的变量可能是合理的,但在教学环境中并不是特别有启发性。如果我按如下方式重写它,它可能会帮助你理解正在发生的事情。
public class Test
{
public static void main(String args[])
{
Computer computer = new Computer();
Computer computerWithDisk = new DiskAddition(computer);
Computer computerWithDiskAndMonitor = new MonitorAddition(computerWithDisk);
Computer computerWithDiskMonitorAndCD = new CDAddition(computerWithDiskAndMonitor);
Computer computerWithDiskMonitorAnd2CDs = new CDAddition(computerWithDiskMonitorAndCD);
System.out.println("You're getting a " + computer.description()
+ ".");
}
}
答案 2 :(得分:0)
每次他创建一个新对象时,他都会传入现有对象,并且该新对象会保存旧对象。因此,每个新的都保存了前一个,并且在其描述函数中,它还调用其保存的组件的描述。
答案 3 :(得分:0)
可能是:
Computer computer1 = new Computer();
Computer computer2 = new Disk(computer1);
Computer computer3 = new Monitor(computer2);
Computer computer4 = new CD(computer3);
Computer computer5 = new CD(computer4);
变量computer
正在被重用