需要一些包装类模式的帮助

时间:2011-01-21 18:10:25

标签: java design-patterns

我正在阅读装饰设计模式,无法理解一些事情 我有四个班级

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

4 个答案:

答案 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正在被重用