Ранее мы проверили схему адаптера , варианты использования и схему моста . Шаблон, который мы рассмотрим в этом посте, является составным шаблоном.
Следуя составному шаблону, мы «объединяем» объекты в древовидные структуры, представляющие частично-целые иерархии, поэтому клиенты могут обрабатывать отдельные объекты и композиции единообразно.
При упоминании иерархий слов первое, что приходит на ум, — это организации. Военная организация является отличным примером для сложной модели.
Одним из самых основных действий военнослужащих является выполнение заказов.
Таким образом, мы сделаем интерфейс, который определяет возможность выполнения заказов.
|
1
2
3
4
5
6
7
|
package com.gkatzioura.design.structural.composite;public interface MilitaryPersonnel { void executeOrder();} |
Рядовой является самым низким званием в военной организации. Частное лицо не может делегировать задачу или отдавать приказы. Поэтому он просто выполнит заказ.
|
01
02
03
04
05
06
07
08
09
10
|
package com.gkatzioura.design.structural.composite;public class Private implements MilitaryPersonnel { @Override public void executeOrder() { }} |
Выше рядового есть и другие звания, такие как майор, лейтенант, полковник и т. Д. Это офицерские звания, а офицеры выполняют приказы, но они также могут назначать приказы.
Так что интерфейс Officer будет указывать возможность назначать заказы.
|
1
2
3
4
5
6
7
|
package com.gkatzioura.design.structural.composite;public interface Officer { void assignOrder();} |
Имейте в виду, что офицер, чтобы выполнить приказ, он предпримет некоторые действия самостоятельно, и он мог бы также назначить некоторые приказы персоналу более низкого ранга.
Таким образом, лейтенант сможет выполнять приказы, а также назначать приказы на звания ниже его.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
package com.gkatzioura.design.structural.composite;import java.util.ArrayList;import java.util.List;public class Lieutenant implements MilitaryPersonnel, Officer { private List<MilitaryPersonnel> lowerRankersonel = new ArrayList<>(); public Lieutenant(List<MilitaryPersonnel> lowerRankersonel) { this.lowerRankersonel = lowerRankersonel; } public void addPrivateUnderCommand(Private soldier) { lowerRankersonel.add(soldier); } @Override public void executeOrder() { //other actions assignOrder(); //other actions. } @Override public void assignOrder() { lowerRankersonel.forEach(lr->lr.executeOrder()); }} |
То же самое относится и к лейтенанту, относится к майору, который может выполнять приказы и назначать приказы более низким званиям.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
package com.gkatzioura.design.structural.composite;import java.util.ArrayList;import java.util.List;public class Colonel implements MilitaryPersonnel, Officer { private List<MilitaryPersonnel> lowerRankersonel = new ArrayList<>(); public Colonel(List<MilitaryPersonnel> lowerRankersonel) { this.lowerRankersonel = lowerRankersonel; } public void addPrivateUnderCommand(Private soldier) { lowerRankersonel.add(soldier); } public void addLieutenantUnderCommand(Lieutenant lieutenant) { lowerRankersonel.add(lieutenant); } @Override public void executeOrder() { //other actions assignOrder(); //other actions } @Override public void assignOrder() { lowerRankersonel.forEach(lr->lr.executeOrder()); }} |
В нашем сценарии общее является наивысшим рангом, и поэтому, когда он назначит ордер, этот ордер будет выполнен с помощью композита, который мы реализовали.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
package com.gkatzioura.design.structural.composite;import java.util.ArrayList;import java.util.List;public class General implements Officer { private List<MilitaryPersonnel> lowerRankersonel = new ArrayList<>(); public General(List<MilitaryPersonnel> lowerRankersonel) { this.lowerRankersonel = lowerRankersonel; } @Override public void assignOrder(MilitaryPersonnel militaryPersonnel) { militaryPersonnel.executeOrder(); }} |
А основной класс будет отображать функциональность композита.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
package com.gkatzioura.design.structural.composite;import java.util.Collections;public class CompositeScenario { public static void main(String[] args) { Private ryan = new Private(); Lieutenant lieutenant = new Lieutenant(Collections.singletonList(ryan)); Major major = new Major(Collections.singletonList(lieutenant)); General general = new General(); general.assignOrder(major); }} |
Как видно из общего объекта, клиент обрабатывает все объекты одинаково.
Вся иерархия представлена в виде древовидной структуры.
Private — это лист Major, а лейтенант представляет Composite, который перенаправляет запросы в соответствующие дочерние компоненты.
Вы можете найти исходный код на github .
| Опубликовано на Java Code Geeks с разрешения Эммануила Гкациоураса, партнера нашей программы JCG. См. Оригинальную статью здесь: Структурные Проектные Образцы: Составной Образец
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |