1. 程式人生 > >【Java】組合模式

【Java】組合模式

組合(Composite)模式,將物件組合成樹形結構以表示“部分-整體”的層次結構,組合模式使得使用者對單個物件和組合物件的使用具有一致性。

組合模式可以讓客戶端像修改配置檔案一樣簡單的完成本來需要流程控制語句來完成的功能。

如下圖所示:


設計模式中的組合模式將物件組合成樹形結果以表示“部分-整體”的層次結構,使得客戶對單個物件和組合物件的使用具有一致性。上圖為該模式的類圖,其中Composite定義有子部件的那些部件的行為,組合部件的物件由Client通過Component提供的介面操作。

Component是組合中的物件宣告介面,在適當的情況下,實現所有類共有介面的預設行為。宣告一個介面用於訪問和管理Component子部件。

Leaf在組合中表示葉子結點物件,葉子結點沒有子結點。Composite定義有枝節點行為,用來儲存子部件,在Component介面中實現與子部件有關操作,如增加(add)和刪除(remove)等。

具體來說,組合模式要在程式語言中實現,其實與《【C++】裝飾器模式》(點選開啟連結)差不多,最終實現之後,讀取、操作某一個類,會一直追本溯源,找到最根本的類,然而其實現卻是像《【C++】觀察者模式》(點選開啟連結)一樣,把要操作的類不停地塞入陣列,在最終要讀取、操作的時候,對基類的陣列進行遍歷,同時其還可以任意對整體的各個部分操作。

下面用一道2010年下半年的軟體設計師的軟考說明這個問題,題目是這樣的:某公司的組織結構圖如圖6-1所示,現採用組合(Composition)設計模式來設計,得到如圖6-2所示的類圖。



其中Company為抽象類,定義了在組織結構圖上新增(Add)和刪除(Delete)分公司、辦事處或者部分的方法介面,類ConcreteCompany表示具體的分公司或者辦事處,分工是或者辦事處下可以設定不同的部門。類HRDepartment和FinanceDepartment分別表示人力資源部和財務部。

具體程式碼如下:

import java.util.*;

//抽象公司類
abstract class Company {
	private String name;

	public Company(String name) {
		super();
		this.name = name;
	}

	public Company() {
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	protected abstract void add(Company company);

	protected abstract void remove(Company company);

	protected abstract void display(int depth);
}

//具體公司類,Concrete除了指 n.水泥 還有 adj.具體的(相對於 abstract adj.抽象的 而言)得意思
class ConcreteCompany extends Company {
	private List<Company> cList;//搞個數組用來存放下級公司

	public ConcreteCompany() {
		cList = new ArrayList<Company>();
	}

	public ConcreteCompany(String name) {
		super(name);//這裡其實同,this.name=name,其中name指代從抽象公司類的Company中繼承下來的類成員name
		cList = new ArrayList<Company>();
	}

	@Override
	protected void add(Company company) {
		cList.add(company);
	}

	@Override
	protected void display(int depth) {//根據級別的不同,級別越低前面的橫線越多
		StringBuilder sb = new StringBuilder("");
		for (int i = 0; i < depth; i++) {
			sb.append("-");
		}
		System.out.println(new String(sb) + this.getName());//列印橫線與當前公司的名詞
		for (Company c : cList) {
			c.display(depth + 2);//每下一級,前面的橫條就多2
		}
	}

	@Override
	protected void remove(Company company) {
		cList.remove(company);
	}
}

//這兩個類,其實也是公司的子類,然而,其沒有存放公司類的陣列,故,註定是一個葉子節點,下面不得有子節點
//也就是斷子絕孫的結點
class HRDepartment extends Company {
	public HRDepartment(String name) {
		super(name);
	}

	@Override
	protected void add(Company company) {
	}

	@Override
	protected void display(int depth) {
		StringBuilder sb = new StringBuilder("");
		for (int i = 0; i < depth; i++) {
			sb.append("-");
		}
		System.out.println(new String(sb) + this.getName());
	}

	@Override
	protected void remove(Company company) {
	}
}
//根本與HRDepartment是一模一樣的,不解釋。
class FinanceDepartment extends Company {
	public FinanceDepartment(String name) {
		super(name);
	}

	@Override
	protected void add(Company company) {
	}

	@Override
	protected void display(int depth) {
		StringBuilder sb = new StringBuilder("");
		for (int i = 0; i < depth; i++) {
			sb.append("-");
		}
		System.out.println(new String(sb) + this.getName());
	}

	@Override
	protected void remove(Company company) {
	}
}

//具體實現
public class CompositionTest {
	public static void main(String[] args) {
		//先搞一個 北京總部
		Company Beijing = new ConcreteCompany();
		Beijing.setName("北京公司總部");
		Beijing.add(new HRDepartment("總公司人力資源部"));
		Beijing.add(new FinanceDepartment("總公司財務部"));
		//再搞一個 上海分公司
		Company Shanghai = new ConcreteCompany("上海分公司");
		Shanghai.add(new FinanceDepartment("上海辦事處財務部"));
		Shanghai.add(new HRDepartment("上海辦事處人力資源部"));
		
		Beijing.add(Shanghai);//將上海分公司置於北京總部之下
		
		//下邏輯同,不解釋了
		Company NanJing = new ConcreteCompany("南京辦事處");
		NanJing.add(new FinanceDepartment("南京辦事處財務部"));
		NanJing.add(new HRDepartment("南京辦事處人力資源部"));
		Shanghai.add(NanJing);
		Beijing.display(0);
	}
}

執行結果如下所示:


符合題意,最後一句Beijing.display(0),是各個部門前面的橫線從0開始,每下一級,多2條橫線。

這裡同時說一下,抽象類與介面的不同。

就是 抽象類裡面除了定義抽象方法外,還可以定義類成員,其子類可以用super(某某類成員)拿下來用,彷如自己定義類成員一般。

而 接口裡面只能定義 抽象方法。

就這麼簡單。

相關推薦

Java組合模式

組合(Composite)模式,將物件組合成樹形結構以表示“部分-整體”的層次結構,組合模式使得使用者對單個物件和組合物件的使用具有一致性。 組合模式可以讓客戶端像修改配置檔案一樣簡單的完成本來需要流程控制語句來完成的功能。 如下圖所示: 設計模式中的組合模式將物件組合成

大戰設計模式13—— 組合模式

component 二叉樹 whole 全部 通過 節點 十分 基礎 進行 組合模式(Composite) 設計模式使用的例子https://github.com/LinkinStars/DesignPatternsAllExample 一、定義 組合多個

Java代理模式

        代理模式的定義:為其他物件提供一種代理以控制對這個物件的訪問。在某些情況下,一個物件不適合或者不能直接引用另一個物件,而代理物件可以在客戶端和目標物件之間起到中介的作用。   【分類】    

JAVA設計模式之單例模式

懶漢 常見 單例 str 自己 餓漢式 span color 實例 前言 java最常見的設計模式就是單例模式,而單例模式最常見的就是懶漢式和餓漢式,現在就分別看一下 1.懶漢式 懶漢式比較懶,當別人用到時才會初始化實例,而當有多個人同時用到就可能產生多個實例,造成線程

Java設計模式:深入理解單例模式

什麼是設計模式?簡單的理解就是前人留下來的一些經驗總結而已,然後把這些經驗起了個名字叫Design Pattern,翻譯過來就是設計模式,通過使用設計模式可以讓我們的程式碼複用性更高,可維護性更高,讓你的程式碼寫的更優雅。設計模式理論上有23種,今天就先來

JavaReactor模式

Reactor是網路程式設計中的一種設計模式。那麼為什麼需要它呢? 最最原始的網路程式設計思路就是伺服器用一個while迴圈,不斷監聽埠是否有新的套接字連線,如果有,那麼就呼叫一個處理函式處理,類似: while(true){ socket = accept();

Java日誌知識總結和經常使用組合配置(commons-logging,log4j,slf4j,logback)

ng- binder mono leading black auto erb param 1.2 Log4j Apache的一個開放源碼項目,通過使用Log4j,我們能夠控制日誌信息輸送的目的地是控制臺、文件、GUI組件、甚至是套接口服務 器

技術累積java30代理模式

基礎 代理模式是Java常見的設計模式之一。所謂代理模式是指客戶端並不直接呼叫實際的物件,而是通過呼叫代理,來間接的呼叫實際的物件。 什麼是代理 參考現實生活中的代理 比如某個品牌的某個省的代理商,作為客戶我們只會跟省代理這邊買東西,而不會直接跟廠商接觸。這裡的代理,是商家代理了品牌。 所

Java-POJO-設計模式JavaEE中的POJO與設計模式中多型繼承的衝突

最近看《重構》談到利用OO的多型來優化 if else 和 switch 分支語句,但是我發現OO語法中的多型在使用框架的JavaEE中是無法實踐的。對此,我感到十分的疑惑,加之之前專案中有個“狀態模式”類的模組被頻繁改動的需求折磨要死,又去看了《設計模式》。《設計模式》中也是強調,使

java——單例模式學習理解

    單例模式,總而言之還是多種多樣的,理解不同的單例模式,對於開發過程中更是極為方便,以下彙總幾種單例的使用,積累備用。     一、只適合單執行緒環境 package test; /** * @author xiao

設計模式組合模式

模式定義 組合模式允許你將物件組合成樹形結構來表現“整體/部分”層次結構。組合能讓客戶以一致的方式處理個別對象以及物件組合。 下圖是該模式的類圖: 可以實現下圖的需求: 一個生動的例子 元件抽象類: public abstract class MenuCompon

Java執行緒安全的單例模式----靜態內部類

單例模式作為一種常見的設計模式,在程式中非常常見,主要是為了保證一個類只有一個唯一的物件。 從簡單的“餓漢式”、“懶漢式”→利用 synchronized 和 複雜的“雙重校驗DCL模式”,是一個考慮執行緒安全的過程(其實靜態的餓漢式單例模式也是執行緒安全的,

Java 單例模式Java 單例模式在多執行緒環境中可能存在的問題

在多執行緒環境下,使用延遲載入的方式實現單例模式,會出現錯誤。 例如,使用如下方式實現單例類: package study20170307; /** * Created by apple on 17/3/7. */ public class Sin

JAVA基礎:設計模式(單例設計模式,工廠設計模式

設計模式:解決某一類問題最行之有效的方法。 java中有23種設計模式。 建立型模式(5種):工廠方法模式,抽象工廠模式,單例模式,建造者模式,原型模式。 結構型模式(7種):介面卡模式,裝飾器模式,代理模式,外觀模式,橋接模式,組合模式,享元模式。 行為型模式(11種):策略模式、模板方法

設計模式學習筆記組合模式

組合模式,適用於樹狀結構。模式有三個角色:組合部件,合成模組,葉子。組合部件是組合其餘兩者的父類。它是一個提供公共屬性,方法的抽象類。合成模組用於合成最終的組合物件,葉子節點是組合部件的底層,也就相當於樹枝與樹葉。該模式又為安全模式和透明模式。兩者卻別在於父類是否提供用於合成元件的所有方法。

單例模式的七種寫法java

第一種(懶漢,執行緒不安全): public class Singleton { private static Singleton instance; private Singleton (){} public static Si

Java生產者消費者模式的實現

前言 生產者消費者問題是執行緒模型中的經典問題:生產者和消費者在同一時間段內共用同一儲存空間,生產者向空間裡生產資料,而消費者取走資料。 阻塞佇列就相當於一個緩衝區,平衡了生產者和消費者的處理能力。這個阻塞佇列就是用來給生產者和消費者解耦的。 wa

重構組合查詢——模板模式

#前言 在進行機房重構的時候,我們學了那麼久的設計模式,不斷理解,抽象具體化,都不如來一個實際的,操作一下! 俗話說:“實踐是檢驗真理的唯一標準!”所以今天我們將模板模式和組合查詢結合到一塊,你會發現組合查詢原來可以這麼簡單! #模板模式 我們要使用模板設計模式

javaFactory工廠模式的應用

一、簡介工廠模式(factory)是設計模式的一種,它類比了工廠中的生產方式:對外只提供產品的選擇,整個產品的生成由內部完成。工廠模式由工廠方法和抽象工廠兩種實現方式。工廠模式簡單來說,就是使用一個工廠類來代替new關鍵字,完成對各種物件的例項化。這樣做的好處,就是可以避免重

Java裝飾器模式

本文主要是介紹《【C++】裝飾器模式》(點選開啟連結)的Java版。關於什麼是裝飾器模式就不再贅述了,這次主要說明從UML類圖是如何與程式碼聯絡起來的。 還是從2012年上半年軟體設計師的軟考題來說明這個例子。 題目是這樣的:某咖啡店當賣咖啡時,可以根據顧客的要求在其中加入