Нужна помощь с шаблоном класса оболочки - PullRequest
0 голосов
/ 21 января 2011

Я читаю шаблон декоративного дизайна и не могу понять несколько вещей У меня четыре класса

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 ]

3 голосов
/ 21 января 2011

Это то, что делает шаблон декоратора. Он «украшает» существующий объект новыми атрибутами.

Итак, последний оформленный объект, который у вас есть, - это CD объект, чей закрытый член computer имеет тип Computer. Но этот computer объект создан Monitor, у которого также есть закрытый член с именем computer. Этот шаблон повторяется до тех пор, пока вы не достигнете исходного объекта Computer.

Теперь, когда вы звоните description(), вы делаете computer.description() плюс некоторый текст для текущего класса. Этот первый вызов проходит по всей цепочке, пока вы не достигнете первого компьютерного объекта, который печатает computer, затем and a disk с объекта Disk, а затем and a monitor с объекта Monitor и, наконец, and a CD от объекта CD.

Вы могли бы использовать новую переменную каждый раз и передавать этот объект в каждый последующий объект. Это зависит от того, что вы ищете. Здесь вы просто повторно используете переменную.

Это искусство ASCII может помочь вам понять отношения между объектами. computer в каждом поле относится к частному члену каждого класса.

     CD           Monitor          Disk          Computer
 __________     ___________     ___________     ___________
| computer-|---|->computer-|---|->computer-|---|->computer |
|__________|   |___________|   |___________|   |___________|

Теперь в следующем искусстве ASCII вы видите, что печатает каждая «коробка». Стрелка сверху показывает порядок выполнения оператора возврата в каждом методе description(). Стрелка между полями показывает порядок, в котором каждый метод description() называется

                           order of print
                  <-------------------------------------------------------------------+
                      CD             Monitor             Disk           Computer      |
                                                                                      |
 call from Main    __________     _______________     ____________     __________     |
----------------> | and a cd |-->| and a monitor |-->| and a disk |-->| computer |----+
                  |__________|   |_______________|   |____________|   |__________|

Надеюсь, мое дерьмовое искусство ASCII поможет:)

1 голос
/ 21 января 2011

Смысл шаблона декоратора состоит в том, чтобы наложить новое поведение поверх существующего поведения.В этом случае дело в том, что вы создаете компьютер, добавляя новые периферийные устройства.Одна вещь, которая может сбить вас с толку, заключается в том, что имена классов не особенно подходят для поведения.Например, я бы, вероятно, назвал бы это 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() 
      + ".");
  }
}
0 голосов
/ 21 января 2011

Это могло быть:

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 только что используется

0 голосов
/ 21 января 2011

Каждый раз, когда он создает новый объект, он переходит в существующий, и этот новый объект сохраняет старый.Таким образом, каждый новый сохраняет предыдущее, и в своей функции описания он также вызывает описание своего сохраненного компонента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...