Шаблон декоратора является одним из лучших способов добавления объектов к объекту без изменения его интерфейса. Я часто использую составные декораторы и всегда спрашиваю себя, как их проектировать, когда список функций должен быть настраиваемым. Я не уверен, что у меня есть правильный ответ, но вот немного пищи для размышлений.
Допустим, у меня есть список номеров:
1
2
3
|
interface Numbers { Iterable<Integer> iterate(); } |
Теперь я хочу создать список, в котором будут только нечетные, уникальные, положительные и отсортированные числа. Первый подход вертикальный (я только что придумал это название):
01
02
03
04
05
06
07
08
09
10
11
12
13
|
Numbers numbers = new Sorted( new Unique( new Odds( new Positive( new ArrayNumbers( new Integer[] { - 1 , 78 , 4 , - 34 , 98 , 4 , } ) ) ) ) ); |
Второй подход — горизонтальный (опять же, имя, которое я придумал):
01
02
03
04
05
06
07
08
09
10
11
12
13
|
Numbers numbers = new Modified( new ArrayNumbers( new Integer[] { - 1 , 78 , 4 , - 34 , 98 , 4 , } ), new Diff[] { new Positive(), new Odds(), new Unique(), new Sorted(), } ); |
Увидеть разницу? Первый подход декорирует ArrayNumbers
«по вертикали», добавляя функциональность через составные декораторы « Positive
, « Odds
, « Unique
и « Sorted
.
Второй подход представляет новый интерфейс Diff
, который реализует базовую функциональность итерации чисел через экземпляры Positive
, Odds
, Unique
и Sorted
:
1
2
3
|
interface Diff { Iterable<Integer> apply(Iterable<Integer> origin); } |
Для пользователя numbers
оба подхода одинаковы. Разница только в дизайне. Какой из них лучше и когда? Кажется, что вертикальное декорирование проще в реализации и больше подходит для небольших объектов, которые предоставляют всего несколько методов.
Что касается моего опыта, я всегда склонен начинать с вертикального декорирования, поскольку его легче реализовать, но в конечном итоге перейти к горизонтальному, когда число декораторов начинает расти.
Ссылка: | Вертикальное и горизонтальное оформление от нашего партнера JCG Егора Бугаенко в блоге About Programming . |