詳解組合模式及商品識別樹例題

組合模式

有時又叫做部分-整體模式(Part-Whole) 。組合模式將對象組織到樹結構中,可以用來描述整體與部分的關係。組合模式可以使客戶端將單純元素與複合元素同等看待。

何時使用

  • 需求中是體現部分與整體層次的結構時
  • 希望用戶忽略組合對象與單個對象的不同, 統一的使用組合結構中的所有對象時

優點

  • 定義了包含基本對象和組合對象的類層次結構
    基本對象可以組合成組合對象,組合對象又能組合成更復雜的組合對象,可以不斷地遞歸組合下去,從而構成-一個統一的組 合對象的類層次結構
  • 統一了組合對象和葉子對象
  • 簡化了客戶端調用
    不用區分組合對象和葉子對象
  • 更容易擴展
    由於客戶端是統一的面對Component來操作,因此,新定義的Composite或leaf子類能夠很容易的與已有的結構一起工作,而不需改變客戶端

缺點

  • 很難限制組合中的組件類型
    這是容易添加新的組件帶來的問題,在需要檢測組件類型的時候,使得我們不能依靠編譯期的類型約束來完成,必須在運行期間動態檢測

本質

  • 統一葉子對象和組合對象

角色

  • 抽象構件(Component)角色:這是一個抽象角色,它給參與組合的對象規定一個接口。這個角色給出共有接口及其默認行爲。
  • 樹葉構件(Leaf)角色:代表參加組合的樹葉對象。一個樹葉對象沒有下級子對象。
  • 樹枝構件(Composite)角色:代表參加組合的有子對象的對象,並給出樹枝構件對象的行爲。

組合模式的目的

  • 讓客戶端不再區分操作的是組合對象還是葉子對象,而是以一種統一的方式來操作

對象樹

  • 組合模式會組合出樹形結構來,這也就意味着,所有可以使用對象樹來描述或操作的功能,都可以考慮使用組合模式

組合模式的實現根據所實現接口的區別分爲兩種形式,分別稱爲安全模式和透明模式( 優缺點是互補的) 組合模式可以不提供父對象的管理方法,但組合模式必須在合適的地方提供子對象的管理方法(諸如add、remove、Display等)。

商品識別樹代碼及UML圖如下

在這裏插入圖片描述
根節點:

public abstract class Component {

	protected String name;

	public Component(String name) {
		super();
		this.name = name;
	}
	public abstract void add(Component component);
	public abstract void remove(Component component);
	public abstract void display(int dept);
}

葉子結點:

public class Leaf extends Component {

	/**
	 * @param name
	 */
	public Leaf(String name) {
		super(name);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void add(Component component) {
		System.out.println("Cannot add to a leaf");
	}

	@Override
	public void remove(Component component) {
		System.out.println("Cannot remove from a leaf");

	}

	@Override
	public void display(int dept) {
		String str="";
		for(int i=0;i<dept;i++) {
			str+="-";
		}
		System.out.println(str+name);
	}

}

樹枝:

public class Composite extends Component {

	private List<Component>children=new ArrayList<Component>();
	public Composite(String name) {
		super(name);
	}

	@Override
	public void add(Component component) {
		children.add(component);
	}

	@Override
	public void remove(Component component) {
		children.remove(component);

	}

	@Override
	public void display(int dept) {
		String str="";
		for(int i=0;i<dept;i++) {
			str+="-";
		}
		System.out.println(str+name);
		for (Component component : children) {
            component.display(dept + 2);
        }
	}

}

客戶端:

public class Main {

	public static void main(String[] args) {
		System.out.println("商品識別樹");
		Component root = new Composite("服裝");

        Composite comp1 = new Composite("男裝");
        comp1.add(new Leaf("襯衣"));
        comp1.add(new Leaf("夾克"));
        root.add(comp1);
        Composite comp2 = new Composite("女裝");
        comp2.add(new Leaf("襯衣"));
        comp2.add(new Leaf("夾克"));
        root.add(comp2);
        
        root.display(1);

	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章