コンビネーションモード
例
さまざまなグラフィックを描画できる描画システムがあります。線、長方形、円を描画できるようになったとします。
抽象クラスを定義します。すべてのグラフィックはこのクラスを継承して描画を完了します。
public abstract class Graphics {
/** 绘图 */
public abstract void draw();
}
Line、rectangle、およびcircleは、上記の抽象クラスを実装します。
public class Line extends Graphics {
@Override
public void draw() {
System.out.println("画一条线");
}
}
public class Rect extends Graphics {
@Override
public void draw() {
System.out.println("画一个矩形");
}
}
public class Circle extends Graphics {
@Override
public void draw() {
System.out.println("画一个圆形");
}
}
次に、上記のさまざまなグラフィックを製図板に追加してから、次のように描画する必要があります。
public class Picture extends Graphics {
private List<Graphics> list = new ArrayList<>();
@Override
public void draw() {
for (Graphics g : list) {
g.draw();
}
}
/** 添加一个图形 */
public void add(Graphics graphics) {
list.add(graphics);
}
/** 移除一个图形 */
public void remove(Graphics graphics) {
list.remove(graphics);
}
/** 获取一个图形 */
public Graphics getChild(int i) {
return list.get(i);
}
}
テストカテゴリ:
public class Test {
public static void main(String[] args) {
Picture picture = new Picture();
picture.add(new Line());
picture.add(new Rect());
picture.add(new Circle());
picture.draw();
}
}
コンビネーションモード
定義
複合モードは、パーツ全体モードとも呼ばれます。複合モードは、オブジェクトをツリー構造に編成し、全体とパーツの関係を記述するために使用できます。複合モードを使用すると、クライアントは単純な要素と複合要素を同等に扱うことができます。 。
意図
オブジェクトをツリー構造に結合して、「部分全体」の階層構造を表します。結合モードを使用すると、ユーザーは単一のオブジェクトと結合されたオブジェクトを一貫して使用できます。
主に問題を解決する
クライアントプログラムは、単純な要素のような複雑な要素を処理できるため、クライアントプログラムを複雑な要素の内部構造から切り離すことができます。
長所と短所
利点:
- 高レベルモジュールの簡単な呼び出し
- ノードは自由に追加できます
短所:
結合モードを使用する場合、そのリーフとブランチの宣言は実装クラスであり、インターフェイスではなく、依存性逆転の原則に違反します。
安全で透過的な組み合わせモード
次の図では、各役割の詳細が省略されて
おり、それぞれのメソッドに関係する役割は示されていません。
- 抽象コンストラクション(コンポーネント)ロール:コンポジションに参加しているオブジェクトのインターフェイスを指定します。このロールは、共通のインターフェイスとデフォルトの動作を提供します。
- リーフの役割:組み合わせに参加しているリーフオブジェクトを表し、リーフには下位のサブオブジェクトがなく、組み合わせに参加している元のオブジェクトの動作を定義します。
- ブランチ構築(複合)ロール:組み合わせに参加しているサブオブジェクトを持つオブジェクトを表し、ブランチオブジェクト構築の動作を提供します
複合オブジェクトには、他のコンポーネントタイプのオブジェクトを含めることができます。つまり、他のブランチオブジェクトとリーフオブジェクトを含めることができます。
安全な合成モードの構造
集約を管理するために必要なメソッドは、リーフ構築クラスではなく、ブランチ構築クラスにのみ表示されます。つまり、サブクラスオブジェクトを管理するメソッドは、Compositeクラスで宣言されます。関連
する役割:
- 抽象コンストラクション(コンポーネント)ロール:コンポジションに参加するオブジェクトのインターフェイスを指定します。このロールは、すべてのサブオブジェクトを管理するために使用できる共通のインターフェイスとデフォルトの動作を提供します。セーフコンポジションモードでは、コンストラクションロールは次のようになります。サブオブジェクトを管理する方法を定義するのではなく、この定義はブランチ構築によって与えられます
- リーフの役割:組み合わせに参加しているリーフオブジェクトを表し、リーフには下位のサブオブジェクトがなく、組み合わせに参加している元のオブジェクトの動作を定義します。
- ブランチ構築(複合)ロール:組み合わせに参加するサブオブジェクトを持つオブジェクトを表し、ブランチオブジェクト構築の動作を提供します。追加、削除など、サブオブジェクトを管理するすべてのメソッドを提供します。
対応するソースコードは次のとおりです。
public interface Component {
/** 返还自己的实例 */
Composite getComposite();
/** 某个商业方法 */
void sampleOperation();
}
public class Composite implements Component {
private List<Component> compositeList = new ArrayList<>();
@Override
public Composite getComposite() {
return this;
}
@Override
public void sampleOperation() {
compositeList.forEach(v -> {
v.sampleOperation();
});
}
public void add(Component component) {
compositeList.add(component);
}
public void remove(Component component) {
compositeList.remove(component);
}
public List<Component> components() {
return compositeList;
}
}
public class Leaf implements Component {
@Override
public Composite getComposite() {
return null;
}
@Override
public void sampleOperation() {
}
}
透明な複合モード構造
透過合成モードでは、ブランチかリーフかに関係なく、すべての特定の構築クラスが固定インターフェースを実装する必要があります
。関連する役割:
- 抽象構造(コンポーネント)ロール:組み合わせに参加するオブジェクトのインターフェースを指定します。このロールは、共通のインターフェースとデフォルトの動作を提供します。すべてのサブオブジェクトを管理するために使用できます。サブオブジェクトを管理するためのすべてのメソッドを提供します。 。追加、削除など。
- リーフの役割:組み合わせに参加しているリーフオブジェクトを表し、リーフには下位のサブオブジェクトがなく、組み合わせに参加している元のオブジェクトの動作を定義します。
- ブランチ構築(複合)ロール:組み合わせに参加しているサブオブジェクトを持つオブジェクトを表し、ブランチオブジェクト構築の動作を提供します
対応するソースコードは次のとおりです。
public interface Component {
/** 返还自己的实例 */
Composite getComposite();
/** 某个商业方法 */
void sampleOperation();
/** 增加一个子构建对象 */
void add(Component component);
/** 删除一个子构建对象 */
void remove(Component component);
/** 返回所有的构建对象 */
List<Component> components();
}
public class Composite implements Component {
private List<Component> compositeList = new ArrayList<>();
@Override
public Composite getComposite() {
return this;
}
@Override
public void sampleOperation() {
compositeList.forEach(v -> {
v.sampleOperation();
});
}
@Override
public void add(Component component) {
compositeList.add(component);
}
@Override
public void remove(Component component) {
compositeList.remove(component);
}
@Override
public List<Component> components() {
return compositeList;
}
}
public class Leaf implements Component {
@Override
public Composite getComposite() {
return null;
}
@Override
public void sampleOperation() {
}
@Override
public void add(Component component) {
}
@Override
public void remove(Component component) {
}
@Override
public List<Component> components() {
return null;
}
}
老僧と若僧の物語
かつては山とお寺がありました。お寺には小さな僧侶に話をしているお年寄りの僧侶がいました。お話は山とお寺の話です。小さな僧侶に物語を語っていたお寺…
ここでの話は、山、寺院、僧侶を含む上記の枝の構造であり、山、寺院、僧侶は葉で作られています。内部の特徴はありません。
ストーリーオブジェクトには、山のオブジェクト、寺院のオブジェクト、僧侶のオブジェクト、ストーリーオブジェクトなどが含まれます。
対応するサンプルコードは次のとおりです
。ストーリーテリングのインターフェイス。つまり、ストーリーは抽象的な構築の役割です。
public interface StoryComponent {
/** 讲故事 */
void tellStory();
}
以下は、ビルドを離れる役割、つまりストーリーです。
public class StoryComposite implements StoryComponent {
private List<StoryComponent> componentList = new ArrayList<>();
@Override
public void tellStory() {
for (StoryComponent s : componentList) {
s.tellStory();
if (s.getClass().getName().contains("MonkLeaf")) {
tellStory();
}
}
}
public void add(StoryComponent component) {
componentList.add(component);
}
public void remove(StoryComponent component) {
componentList.remove(component);
}
public List<StoryComponent> getChild() {
return componentList;
}
}
以下は、子オブジェクトのない山、寺院、僧侶です。
public class MountainLeaf implements StoryComponent {
@Override
public void tellStory() {
System.out.println("从前有座山");
}
}
public class TempleLeaf implements StoryComponent {
@Override
public void tellStory() {
System.out.println("山里有个庙");
}
}
public class MonkLeaf implements StoryComponent {
@Override
public void tellStory() {
System.out.println("庙里有个老和尚,老和尚再给小和尚讲故事,讲的什么故事呢?");
System.out.println("讲的是:");
System.out.println("----------------------------------------------------------------------");
}
}
物語を語り始めました:
public class StoryTest {
public static void main(String[] args) {
//故事
StoryComposite story = new StoryComposite();
//叶子:山、庙、道士
StoryComponent mountain = new MountainLeaf();
StoryComponent temple = new TempleLeaf();
StoryComponent monk = new MonkLeaf();
//添加子构建对象
story.add(mountain);
story.add(temple);
story.add(monk);
//开始讲故事
story.tellStory();
}
}
それからあなたは古い僧侶が疲れ果てているのに気付くでしょう、ハハ。。。
クラス図: