35:合成モード


合成モードはオブジェクトの構造モードであり、部分-全体モードとも呼ばれることがある.
継承に基づくタイプの階層構造はツリー構造であり、合成に基づくオブジェクト構造もツリー構造であり、本章で説明する合成モードもオブジェクトのツリー構造を処理するモードである.
一:ツリー構造の種類がある
(A)上から下へのツリー図---各ツリーノードには矢印がすべてのサブノードを指しているため、クライアントは1つのツリーノードにすべてのサブノードを与えるように要求し、1つのノードは親ノードを知らない.
(B)下から上へのツリー---下から上へのツリーでは、各ノードに矢印が親ノードを指しているが、親ノードはその子ノードを知らない.
(C)双方向のツリー図
二:安全式と透明式の合成モード
合成モードには、次の3つのロールが含まれます.
(A)抽象コンポーネント(Componentロール):これは抽象ロールであり、グループに参加するオブジェクトにインタフェースを規定し、このインタフェースは共通のインタフェースとデフォルトの動作を与える.
(B)リーフコンポーネント(Leaf)キャラクタ:参加グループを表すリーフオブジェクト
(C)木の枝コンポーネント(Component)キャラクタ:サブオブジェクトの組み合わせに参加するオブジェクトを表し、木の枝コンポーネントオブジェクトの動作を与えます.
合成モードは、実装されるインタフェースの違いに応じて、セキュリティ式と透明式の2つの形式に分けられる.透明式は、add()、remove、getChildメソッドを含むすべてのサブクラスオブジェクトを管理するためのメソッドをComponentに宣言し、すべてのコンポーネントクラスに同じインタフェースがあるという利点がある.安全式は、Compositeクラスにおいて、サブクラスオブジェクトの管理を宣言する方法である.
三:以下は安全式の合成モードのソースコードです
package cai.milenfan.basic.test; 

public interface Component { 
//       
Component getComposite(); 
//      
void sampleOperation(); 
} 
package cai.milenfan.basic.test; 

import java.util.Enumeration; 
import java.util.Vector; 

public class Composite implements Component{ 
private Vector componentVector = new java.util.Vector(); 
public Component getComposite() { 
return this; 
} 

public void sampleOperation() { 
Enumeration enumeration = components(); 
while(enumeration.hasMoreElements()){ 
((Component)enumeration.nextElement()).sampleOperation();
} 
} 

//      --         
public void add(Component component){ 
componentVector.addElement(component); 
} 

//      --         
public void remove(Component component){ 
componentVector.remove(component); 
} 

public Enumeration components(){ 
return componentVector.elements(); 
} 
} 
package cai.milenfan.basic.test; 

public class Leaf implements Component{ 
public Component getComposite() { 
//write you code here 
return null; 
} 
public void sampleOperation() { 
//write your code here 
} 
} 

四:透明な合成モードのソースコード
安全式の合成モードとは異なる、透明式の合成モードは、枝部材でも葉部材でも固定的なインタフェースに合致するすべての具体的な部材類を要求する.役割はセキュリティと同じです.コードは次のとおりです.
package cai.milenfan.basic.test; 

import java.util.Enumeration; 

public interface Component { 
//       
Component getComposite(); 
//      
void sampleOperation(); 
//       ,         
void add(Component component); 
//       ,         
void remove(Component component); 
//       ,     Enumeration  
Enumeration components(); 
} 
package cai.milenfan.basic.test; 

import java.util.Enumeration; 
import java.util.Vector; 
//                       ,      ,                  
public class Composite implements Component{ 
private Vector componentVector = new java.util.Vector(); 
public Component getComposite() { 
return this; 
} 

public void sampleOperation() { 
Enumeration enumeration = components(); 
while(enumeration.hasMoreElements()){ 
((Component)enumeration.nextElement()).sampleOperation();
} 
} 

//      --         
public void add(Component component){ 
componentVector.addElement(component); 
} 

//      --         
public void remove(Component component){ 
componentVector.remove(component); 
} 

public Enumeration components(){ 
return componentVector.elements(); 
} 
} 
package cai.milenfan.basic.test; 

import java.util.Enumeration; 

public class Leaf implements Component{ 
public Component getComposite() { 
//write you code here 
return null; 
} 
public void sampleOperation() { 
//write your code here 
} 
public void add(Component component) { 
} 
public Enumeration components() { 
return null; 
} 
public void remove(Component component) { 
} 
} 

五:図面の一例411
合成モードの応用を説明するために、図面ソフトの例を示す.1つの描画システムは、線、長方形、円形などの基本的な図形からなる図形を描くための様々なツールを提供する.明らかに,複合図形がこれらの基本図形から構成されている以上,全成モードは適切な設計モードである.次に、セキュリティ合成モードのコード(透明な自己書き込み)を示します.
package cai.milenfan.basic.test; 
//          
public abstract class Graphics { 
public abstract void draw(); 
} 
package cai.milenfan.basic.test; 

import java.util.Vector; 

public class Picture extends Graphics{ 
private Vector list = new Vector(10); 
public void draw() { 
for(int i=0;i<list.size();i ){ 
Graphics g = (Graphics)list.get(i); 
g.draw(); 
} 
} 

//       ,         
public void add(Graphics g){ 
list.add(g); 
} 
//         
public void remove(Graphics g){ 
list.remove(g); 
} 
//         
public Graphics getChild(int i){ 
return (Graphics)list.get(i); 
} 
} 
package cai.milenfan.basic.test; 
//Line       ,        ,               
public class Line extends Graphics{ 
public void draw() { 
//write your code here 
} 
} 

//長方形、円形の実現はLineと同じ
六:awtライブラリの例
awtとswingのグラフィックインタフェース部材はawtライブラリのContainerクラスとComponentクラスに構築するため、ButtonとCheckboxは木の葉型の部材であり、Containerは枝型の部材である.Containerクラスでは操作集約の方法があるが、Componentクラスではこのような方法はない、awtで使用する合成モードは安全な形式の合成モードである.
以下の場合、合成モードを使用することを考慮すべきである.
(1)オブジェクトの部分と全体の階層構造を記述する必要がある
(2)個々の部材と組合せ部材の違いを無視する必要がある.
利点:新しい種類の部材を容易に追加できる.
欠点:継承手法を用いて新しい行動を増やすことは困難である