Я не видел ту функцию в XCode. Но кажется, что кто-то мог записать новый пользовательский сценарий, названный "Конструктор места Defs на Буфере обмена", который находится в Сценариях> Код.
Вы не нашли это полезным.
Настоящий запах в шаблоне, изображенном в вашей ссылке и в большинстве книг, заключается в том, что Компонент
имеет методы 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, потому что он дает более чистый и менее сложный код. Если бы вы сделали свой код идеально инкапсулированным, гибким, изолированным и т. Д., Вы бы изобрели новый язык программирования: -)
Я бы сказал, что шаблон 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
, что нарушает принцип.