Действительно ли составной шаблон тверд?

Я не видел ту функцию в XCode. Но кажется, что кто-то мог записать новый пользовательский сценарий, названный "Конструктор места Defs на Буфере обмена", который находится в Сценариях> Код.

Вы не нашли это полезным.

11
задан jaco0646 23 October 2018 в 15:29
поделиться

2 ответа

Настоящий запах в шаблоне, изображенном в вашей ссылке и в большинстве книг, заключается в том, что Компонент имеет методы Composite . Я думаю, что это, вероятно, связано с тем, что этот образец довольно старый и повторялся так уже много лет. Я считаю, что только Composite должен иметь какие-либо методы, связанные с композитингом.

Однажды я преобразовал настольную игру в компьютерную. Фигуры размещались на карте земли, разделенной на шестиугольники. 99% всех шестиугольников представляли одну локацию. К сожалению, некоторые из шестиугольников содержали несколько мест, например, внутри некоторых было несколько островов. Я использовал составной узор для представления этих мест, но не так, как показано в вашей ссылке. Это было примерно так (на Java):

public interface Location {
   Set<Army> getArmies();
}

public class SingleLocation implements Location {

   public Set<Army> getArmies() {
      return armies ;
   }

   private Set<Army> armies = new HashSet<Army>();
}

public class CompositeLocation implements Location {

   public Set<Army> getArmies() {

      Set<Army> armies = new HashSet<Army>();

      for(Location subLocation: subLocations) {
         armies.addAll(subLocation.getArmies());
      }

      return armies;
   }

   public void addSubLocation(Location location) {
      subLocations.add(location);
   }

   private Set<Location> subLocations = new HashSet<Location>();
}

Обратите внимание, что только Composite имеет методы компоновки и даже не раскрывает тот факт, что у него есть дочерние элементы для большинства клиентов (в этом примере клиенту нужен только список армий из местоположения - тот факт, что они находятся во многих подобластях, не имеет значения).

Имейте в виду, что шаблоны проектирования не являются каменными вещами, которые вы должны точно реализовать. Думайте о них как о рецептах. Если вы следуете рецепту во время приготовления, вы, безусловно, можете просто точно следовать ему. Однако некоторые повара вносят свой вклад в рецепт. Другие даже не смотрят на это, потому что они эксперты и могут составить что-то в духе рецепта, даже не задумываясь об этом. То же самое и с шаблонами проектирования. Это податливые рецепты.

Вы также можете зайти слишком далеко с этими твердыми принципами. Если вы читаете Роберта Мартина ' В статьях он заявляет, что применение принципов повсеместно без каких-либо размышлений приведет к получению слишком сложного кода. Программное обеспечение разрабатывается с помощью ряда компромиссов и балансировок - иногда вы отказываетесь от чистого SOLID, потому что он дает более чистый и менее сложный код. Если бы вы сделали свой код идеально инкапсулированным, гибким, изолированным и т. Д., Вы бы изобрели новый язык программирования: -)

11
ответ дан 3 December 2019 в 05:34
поделиться

Я бы сказал, что шаблон Composite, описанный в вашей ссылке, нарушает принцип подстановки Лискова , один из пяти принципов SOLID .

Компонент имеет методы, которые имеют смысл только для Composite , например Add () . Leaf наследуется от Компонента , поэтому он будет иметь метод Add () , как и любой другой Компонент . Но Leafs не имеют потомков, поэтому следующий вызов метода не может вернуть значимый результат:

myLeaf.Add (someChild);

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

Следовательно, вы не можете обрабатывать Leaf как любой другой Компонент , потому что вы получите исключение, если попытаетесь. Принцип подстановки Лискова гласит:

Пусть q (x) - свойство, доказуемое относительно объекты x типа T. Тогда q (y) должен быть верным для объектов y типа S, где S является подтипом T.

Компоненты имеют свойство, позволяющее добавлять к ним дочерние элементы. Но вы не можете добавлять дочерние элементы в Leaf , даже если Leaf является подтипом Component , что нарушает принцип.

7
ответ дан 3 December 2019 в 05:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: