工廠方法模式 抽象工廠模式

工廠方法模式

定義:定義一個用於建立對象的接口,讓子類決定實例化哪個類,工廠方法使一個類的實例化延遲到其子類。 java

類型:建立類模式 編程

類圖: 架構

工廠方法模式代碼 spa

  1. interface IProduct { 
  2.     public void productMethod(); 
  3.  
  4. class Product implements IProduct { 
  5.     public void productMethod() { 
  6.         System.out.println("產品"); 
  7.     } 
  8.  
  9. interface IFactory { 
  10.     public IProduct createProduct(); 
  11.  
  12. class Factory implements IFactory { 
  13.     public IProduct createProduct() { 
  14.         return new Product(); 
  15.     } 
  16.  
  17. public class Client { 
  18.     public static void main(String[] args) { 
  19.         IFactory factory = new Factory(); 
  20.         IProduct prodect = factory.createProduct(); 
  21.         prodect.productMethod(); 
  22.     } 

interface IProduct {
	public void productMethod();
}

class Product implements IProduct {
	public void productMethod() {
		System.out.println("產品");
	}
}

interface IFactory {
	public IProduct createProduct();
}

class Factory implements IFactory {
	public IProduct createProduct() {
		return new Product();
	}
}

public class Client {
	public static void main(String[] args) {
		IFactory factory = new Factory();
		IProduct prodect = factory.createProduct();
		prodect.productMethod();
	}
}

工廠模式: .net

        首先須要說一下工廠模式。工廠模式根據抽象程度的不一樣分爲三種:簡單工廠模式(也叫靜態工廠模式)、本文所講述的工廠方法模式、以及抽象工廠模式。工廠模式是編程中常常用到的一種模式。它的主要優勢有: code

  • 可使代碼結構清晰,有效地封裝變化。在編程中,產品類的實例化有時候是比較複雜和多變的,經過工廠模式,將產品的實例化封裝起來,使得調用者根本無需關心產品的實例化過程,只需依賴工廠便可獲得本身想要的產品。
  • 對調用者屏蔽具體的產品類。若是使用工廠模式,調用者只關心產品的接口就能夠了,至於具體的實現,調用者根本無需關心。即便變動了具體的實現,對調用者來講沒有任何影響。
  • 下降耦合度。產品類的實例化一般來講是很複雜的,它須要依賴不少的類,而這些類對於調用者來講根本無需知道,若是使用了工廠方法,咱們須要作的僅僅是實例化好產品類,而後交給調用者使用。對調用者來講,產品所依賴的類都是透明的。


工廠方法模式: 對象

       經過工廠方法模式的類圖能夠看到,工廠方法模式有四個要素: 繼承

  • 工廠接口。工廠接口是工廠方法模式的核心,與調用者直接交互用來提供產品。在實際編程中,有時候也會使用一個抽象類來做爲與調用者交互的接口,其本質上是同樣的。
  • 工廠實現。在編程中,工廠實現決定如何實例化產品,是實現擴展的途徑,須要有多少種產品,就須要有多少個具體的工廠實現。
  • 產品接口。產品接口的主要目的是定義產品的規範,全部的產品實現都必須遵循產品接口定義的規範。產品接口是調用者最爲關心的,產品接口定義的優劣直接決定了調用者代碼的穩定性。一樣,產品接口也能夠用抽象類來代替,但要注意最好不要違反里氏替換原則。
  • 產品實現。實現產品接口的具體類,決定了產品在客戶端中的具體行爲。

        前文提到的簡單工廠模式跟工廠方法模式極爲類似,區別是:簡單工廠只有三個要素,他沒有工廠接口,而且獲得產品的方法通常是靜態的。由於沒有工廠接口,因此在工廠實現的擴展性方面稍弱,能夠算所工廠方法模式的簡化版,關於簡單工廠模式,在此一筆帶過。 接口

      

適用場景: get

        不論是簡單工廠模式,工廠方法模式仍是抽象工廠模式,他們具備相似的特性,因此他們的適用場景也是相似的。

        首先,做爲一種建立類模式,在任何須要生成複雜對象的地方,均可以使用工廠方法模式。有一點須要注意的地方就是複雜對象適合使用工廠模式,而簡單對象,特別是只須要經過new就能夠完成建立的對象,無需使用工廠模式。若是使用工廠模式,就須要引入一個工廠類,會增長系統的複雜度。

       其次,工廠模式是一種典型的解耦模式,迪米特法則在工廠模式中表現的尤其明顯。假如調用者本身組裝產品須要增長依賴關係時,能夠考慮使用工廠模式。將會大大下降對象之間的耦合度。

       再次,因爲工廠模式是依靠抽象架構的,它把實例化產品的任務交由實現類完成,擴展性比較好。也就是說,當須要系統有比較好的擴展性時,能夠考慮工廠模式,不一樣的產品用不一樣的實現工廠來組裝。

      

典型應用

       要說明工廠模式的優勢,可能沒有比組裝汽車更合適的例子了。場景是這樣的:汽車由發動機、輪、底盤組成,如今須要組裝一輛車交給調用者。假如不使用工廠模式,代碼以下:

  1. class Engine { 
  2.     public void getStyle(){ 
  3.         System.out.println("這是汽車的發動機"); 
  4.     } 
  5. class Underpan { 
  6.     public void getStyle(){ 
  7.         System.out.println("這是汽車的底盤"); 
  8.     } 
  9. class Wheel { 
  10.     public void getStyle(){ 
  11.         System.out.println("這是汽車的輪胎"); 
  12.     } 
  13. public class Client { 
  14.     public static void main(String[] args) { 
  15.         Engine engine = new Engine(); 
  16.         Underpan underpan = new Underpan(); 
  17.         Wheel wheel = new Wheel(); 
  18.         ICar car = new Car(underpan, wheel, engine); 
  19.         car.show(); 
  20.     } 

class Engine {
	public void getStyle(){
		System.out.println("這是汽車的發動機");
	}
}
class Underpan {
	public void getStyle(){
		System.out.println("這是汽車的底盤");
	}
}
class Wheel {
	public void getStyle(){
		System.out.println("這是汽車的輪胎");
	}
}
public class Client {
	public static void main(String[] args) {
		Engine engine = new Engine();
		Underpan underpan = new Underpan();
		Wheel wheel = new Wheel();
		ICar car = new Car(underpan, wheel, engine);
		car.show();
	}
}


        能夠看到,調用者爲了組裝汽車還須要另外實例化發動機、底盤和輪胎,而這些汽車的組件是與調用者無關的,嚴重違反了迪米特法則,耦合度過高。而且很是不利於擴展。另外,本例中發動機、底盤和輪胎仍是比較具體的,在實際應用中,可能這些產品的組件也都是抽象的,調用者根本不知道怎樣組裝產品。假如使用工廠方法的話,整個架構就顯得清晰了許多。

  1. interface IFactory { 
  2.     public ICar createCar(); 
  3. class Factory implements IFactory { 
  4.     public ICar createCar() { 
  5.         Engine engine = new Engine(); 
  6.         Underpan underpan = new Underpan(); 
  7.         Wheel wheel = new Wheel(); 
  8.         ICar car = new Car(underpan, wheel, engine); 
  9.         return car; 
  10.     } 
  11. public class Client { 
  12.     public static void main(String[] args) { 
  13.         IFactory factory = new Factory(); 
  14.         ICar car = factory.createCar(); 
  15.         car.show(); 
  16.     } 

interface IFactory {
	public ICar createCar();
}
class Factory implements IFactory {
	public ICar createCar() {
		Engine engine = new Engine();
		Underpan underpan = new Underpan();
		Wheel wheel = new Wheel();
		ICar car = new Car(underpan, wheel, engine);
		return car;
	}
}
public class Client {
	public static void main(String[] args) {
		IFactory factory = new Factory();
		ICar car = factory.createCar();
		car.show();
	}
}

        使用工廠方法後,調用端的耦合度大大下降了。而且對於工廠來講,是能夠擴展的,之後若是想組裝其餘的汽車,只須要再增長一個工廠類的實現就能夠。不管是靈活性仍是穩定性都獲得了極大的提升。

==============================

抽象工廠模式

定義:爲建立一組相關或相互依賴的對象提供一個接口,並且無需指定他們的具體類。

類型:建立類模式

類圖:

抽象工廠模式與工廠方法模式的區別

        抽象工廠模式是工廠方法模式的升級版本,他用來建立一組相關或者相互依賴的對象。他與工廠方法模式的區別就在於,工廠方法模式針對的是一個產品等級結構;而抽象工廠模式則是針對的多個產品等級結構。在編程中,一般一個產品結構,表現爲一個接口或者抽象類,也就是說,工廠方法模式提供的全部產品都是衍生自同一個接口或抽象類,而抽象工廠模式所提供的產品則是衍生自不一樣的接口或抽象類。

        在抽象工廠模式中,有一個產品族的概念:所謂的產品族,是指位於不一樣產品等級結構中功能相關聯的產品組成的家族。抽象工廠模式所提供的一系列產品就組成一個產品族;而工廠方法提供的一系列產品稱爲一個等級結構。咱們依然拿生產汽車的例子來講明他們之間的區別。

        在上面的類圖中,兩廂車和三廂車稱爲兩個不一樣的等級結構;而2.0排量車和2.4排量車則稱爲兩個不一樣的產品族。再具體一點,2.0排量兩廂車和2.4排量兩廂車屬於同一個等級結構,2.0排量三廂車和2.4排量三廂車屬於另外一個等級結構;而2.0排量兩廂車和2.0排量三廂車屬於同一個產品族,2.4排量兩廂車和2.4排量三廂車屬於另外一個產品族。

        明白了等級結構和產品族的概念,就理解工廠方法模式和抽象工廠模式的區別了,若是工廠的產品所有屬於同一個等級結構,則屬於工廠方法模式;若是工廠的產品來自多個等級結構,則屬於抽象工廠模式。在本例中,若是一個工廠模式提供2.0排量兩廂車和2.4排量兩廂車,那麼他屬於工廠方法模式;若是一個工廠模式是提供2.4排量兩廂車和2.4排量三廂車兩個產品,那麼這個工廠模式就是抽象工廠模式,由於他提供的產品是分屬兩個不一樣的等級結構。固然,若是一個工廠提供所有四種車型的產品,由於產品分屬兩個等級結構,他固然也屬於抽象工廠模式了。

抽象工廠模式代碼

  1. interface IProduct1 { 
  2.     public void show(); 
  3. interface IProduct2 { 
  4.     public void show(); 
  5.  
  6. class Product1 implements IProduct1 { 
  7.     public void show() { 
  8.         System.out.println("這是1型產品"); 
  9.     } 
  10. class Product2 implements IProduct2 { 
  11.     public void show() { 
  12.         System.out.println("這是2型產品"); 
  13.     } 
  14.  
  15. interface IFactory { 
  16.     public IProduct1 createProduct1(); 
  17.     public IProduct2 createProduct2(); 
  18. class Factory implements IFactory{ 
  19.     public IProduct1 createProduct1() { 
  20.         return new Product1(); 
  21.     } 
  22.     public IProduct2 createProduct2() { 
  23.         return new Product2(); 
  24.     } 
  25.  
  26. public class Client { 
  27.     public static void main(String[] args){ 
  28.         IFactory factory = new Factory(); 
  29.         factory.createProduct1().show(); 
  30.         factory.createProduct2().show(); 
  31.     } 


 

interface IProduct1 {
	public void show();
}
interface IProduct2 {
	public void show();
}

class Product1 implements IProduct1 {
	public void show() {
		System.out.println("這是1型產品");
	}
}
class Product2 implements IProduct2 {
	public void show() {
		System.out.println("這是2型產品");
	}
}

interface IFactory {
	public IProduct1 createProduct1();
	public IProduct2 createProduct2();
}
class Factory implements IFactory{
	public IProduct1 createProduct1() {
		return new Product1();
	}
	public IProduct2 createProduct2() {
		return new Product2();
	}
}

public class Client {
	public static void main(String[] args){
		IFactory factory = new Factory();
		factory.createProduct1().show();
		factory.createProduct2().show();
	}
}


 

抽象工廠模式的優勢

        抽象工廠模式除了具備工廠方法模式的優勢外,最主要的優勢就是能夠在類的內部對產品族進行約束。所謂的產品族,通常或多或少的都存在必定的關聯,抽象工廠模式就能夠在類內部對產品族的關聯關係進行定義和描述,而沒必要專門引入一個新的類來進行管理。


抽象工廠模式的缺點

       產品族的擴展將是一件十分費力的事情,假如產品族中須要增長一個新的產品,則幾乎全部的工廠類都須要進行修改。因此使用抽象工廠模式時,對產品等級結構的劃分是很是重要的。


適用場景

       當須要建立的對象是一系列相互關聯或相互依賴的產品族時,即可以使用抽象工廠模式。說的更明白一點,就是一個繼承體系中,若是存在着多個等級結構(即存在着多個抽象類),而且分屬各個等級結構中的實現類之間存在着必定的關聯或者約束,就可使用抽象工廠模式。假如各個等級結構中的實現類之間不存在關聯或約束,則使用多個獨立的工廠來對產品進行建立,則更合適一點。


總結

       不管是簡單工廠模式,工廠方法模式,仍是抽象工廠模式,他們都屬於工廠模式,在形式和特色上也是極爲類似的,他們的最終目的都是爲了解耦。在使用時,咱們沒必要去在乎這個模式到底工廠方法模式仍是抽象工廠模式,由於他們之間的演變經常是使人琢磨不透的。常常你會發現,明明使用的工廠方法模式,當新需求來臨,稍加修改,加入了一個新方法後,因爲類中的產品構成了不一樣等級結構中的產品族,它就變成抽象工廠模式了;而對於抽象工廠模式,當減小一個方法使的提供的產品再也不構成產品族以後,它就演變成了工廠方法模式。

       因此,在使用工廠模式時,只須要關心下降耦合度的目的是否達到了。

相關文章
相關標籤/搜索