天天看點

建造者模式(生成器模式)跟着ZHONGHuan學習設計模式建造者模式(生成器模式)

轉載請注明出處!!!http://blog.csdn.net/zhonghuan1992

         所有配套代碼均在github上:https://github.com/ZHONGHuanGit/DesignPattern

跟着ZHONGHuan學習設計模式

建造者模式(生成器模式)

簡介:

         建造者模式也叫做生成器模式,定義為:封裝一個産品的構造過程,并且按此步驟構造。

         建造者模式(生成器模式)屬于建立類模式,和工廠模式相比,你會覺得有點類似,但是有差別之處。不過,建議在看下去之前,得明白三個工廠模式,如果你記得不太清楚了,可以看這裡,簡單工廠,工廠方法,抽象工廠。

UML類圖:

         看一下uml類圖。這一部分,如果不清楚,可以先看下面的場景部分,再回過頭來看。

建造者模式(生成器模式)跟着ZHONGHuan學習設計模式建造者模式(生成器模式)

從上面的類圖中,可以看到有四個要素。

1          AbstractBuilder(抽象建造者):引入抽象建造者的目的,是為了将建造的具體過程交與它的子類來實作。這樣更容易擴充。一般會有兩部分抽象方法,一部分用來建造産品,一個是用來傳回産品。如上面,buildPart1和buildPart2用來構造産品,retrieveResult傳回産品。

2          ConcreteBuilder(具體建造者):實作抽象建造者的抽象方法,之是以這樣,是為了便于不同情況下的擴充。

3          Director(導演者):負責調用适當的建造者來組建産品,導演類一般不與産品類發生依賴關系,與導演類直接互動的是建造者類。一般來說,導演類被用來封裝程式中易變的部分。

4          Product(産品類):一般是一個較為複雜的對象,也就是說建立對象的過程比較複雜,一般會有比較多的代碼量。在本類圖中,産品類是一個具體的類,而非抽象類。實際程式設計中,産品類可以是由一個抽象類與它的不同實作組成,也可以是由多個抽象類與他們的實作組成。

場景導入:

         假設有這樣的要求,去遊樂場玩,遊樂場有很多可以供娛樂的地方。比如有旋轉木馬,過山車,摩天輪,海盜船等等。當我們去玩得時候,至少不會胡來,自己還是有點計劃的對吧。比如,小明想先去玩過山車(比較喜歡刺激的人),接着摩天輪,然後海盜船,最後旋轉木馬;另外一個小朋友也去玩,他想先玩摩天輪,接着。。。。,等等。假設每個人的計劃就是我們需要的産品,那麼,如果你用工廠模式,如何去設計把這個産品生成出來呢,當然,你一定可以想一些方法,即使不合适,但也可行。這裡,比較合适的方法應該是生成器模式。

         重新定義場景:暫時定遊樂場一共有3個活動,分别是,摩天輪,海盜船,過山車。現在我們的産品是要出一份計劃,是先玩哪個,全部玩,還是隻玩一個,這個計劃就是産品。

讓我們看一下實作的代碼:

import java.util.ArrayList;
//假設産品是一份計劃
class Plan{
	public ArrayList<String> list = new ArrayList<String>();
	void add(String str){
		list.add(str);
		System.out.println("将\""+str+"\"加入計劃");
	}
	void Out(){//列印出計劃的内容
		System.out.println("計劃内容如下:");
		for(String tmp:list){
	         System.out.println(tmp);
	    }
	}
}

interface AbstractBuilder{
	void addRollerCoaster();//将過山車加入計劃
	void addFerrisWheel();//将摩天輪加入計劃
	void addPirateShip();//将海盜船加入計劃
	Plan retrievePlan();//傳回計劃
}

class ConcreteBuilder implements AbstractBuilder{
	Plan plan = new Plan();
	public void addRollerCoaster(){//将過山車加入計劃
		plan.add("roller coaster");
	}
	public void addFerrisWheel(){//将摩天輪加入計劃
		plan.add("ferris wheel");
	}
	public void addPirateShip(){//将海盜船加入計劃
		plan.add("pirate ship");
	}
	public Plan retrievePlan()//傳回計劃
	{
		return plan;
	}
}

class Director{
	public void construct(){
		AbstractBuilder builder=new ConcreteBuilder();
		builder.addRollerCoaster();
		builder.addFerrisWheel();
		builder.addPirateShip();
		builder.addRollerCoaster();//玩第二次
		//建構完畢後,我們就得到了我們的計劃
		Plan plan=builder.retrievePlan();
		plan.Out();//列印出計劃的内容
	}
}

public class Main{
	public static void main(String[] args){
		Director dir=new Director();
		dir.construct();
	}
}

           

輸出:

建造者模式(生成器模式)跟着ZHONGHuan學習設計模式建造者模式(生成器模式)

         現在有一個小朋友,他指向玩一個摩天輪,那麼根據他的要求,改變的隻是Director的部分。更改代碼吐下:

class Director{
         public void construct(){
                   AbstractBuilder builder=new ConcreteBuilder();
                   builder.addFerrisWheel();
                   //建構完畢後,我們就得到了我們的計劃
                   Plan plan=builder.retrievePlan();
                   plan.Out();//列印出計劃的内容
         }
}
           

         假設有一個小朋友,計劃玩兩次過山車(刺激男孩),那麼,依舊隻需更改Director的部分。

class Director{
         publicvoid construct(){
                   AbstractBuilder builder=new ConcreteBuilder();
                   builder.addRollerCoaster();
                   builder.addFerrisWheel();
                   builder.addPirateShip();
                   builder.addRollerCoaster();//玩第二次
                   //建構完畢後,我們就得到了我們的計劃
                   Plan plan=builder.retrievePlan();
                   plan.Out();//列印出計劃的内容
         }
}
           

         建造者模式的優點,從上面我們可以體會出一點,product和builder部分一般不變,但是當有新的要求,Director部分可以通過變更滿足這些要求。這種将業務邏輯封裝在導演類(Director)中的方式,對整體而言會有更好的穩定性。

簡單論述工廠與建造者(生成器)模式的差別:

         工廠主要變更的地方是産品的變更,而builder 模式主要變更的地方則是director,就是組裝的變更。工廠更傾向基本元件的生産,而builder是這些基本元件的組裝。個人覺得這兩個是可以結合起來的。工廠更基本,builder更高層。

繼續閱讀