簡單工廠、工廠方法、抽象工廠的總結

簡單工廠,工廠方法,抽象工廠都屬於設計模式中的創建型模式。其主要功能都是幫助我們把對象的實例化部分抽取了出來,優化了系統的架構,並且增強了系統的擴展性。

大白話

如果簡單工廠是用來生產”東西“的,那任何”東西“的子類,比如汽車,自行車,輪船,洗髮水都是可以被生產的,但此處簡單工廠的壓力太大了啊,任何”東西“的子類都可以被生產,負擔太重,所以一般對簡單工廠類也有種稱呼,叫”上帝類“。
而工廠方法模式就很好的減輕了工廠類的負擔,把某一類/某一種東西交由一個工廠生產,同時增加某一類”東西“並不需要修改工廠類,只需要添加生產這類”東西“的工廠即可,使得工廠類符合開放-封閉原則。
對於”東西“的分類,有時候不能光是橫向的分類,從另一個角度也是可以分類的,不知道這句話的意思能不能懂,打個比方:汽車可以根據品牌分爲奔馳、奧迪,也可以根據類別分爲普通三廂車和SUV車,如果用工廠方法來描述的話,奔馳車工廠有一個方法即生產奔馳車,奧迪車工廠有一個方法生產奧迪車,但在有多重分類的情形下,這樣寫已經不夠用,不符合實際了,這個時候需要用到抽象工廠模式,即奧迪車工廠有兩個方法,一個方法是生產普通三廂奧迪車,另一個方法是生產SUV奧迪車。奔馳車工廠有兩個方法,一個方法是生產普通三廂奔馳車,另一個方法是生產SUV奔馳車。
上面即工廠方法模式和抽象工廠模式的應用場景,因爲這兩者很像,所以概念上不容易區分,可以這麼說,工廠方法模式是一種極端情況的抽象工廠模式,而抽象工廠模式可以看成是工廠方法模式的一種推廣。
再說下抽象工廠模式,此處的抽象工廠接口應該是有兩個方法,一個是生成普通三廂車,一個是生產SUV車,可以說,生產的”東西“已經被限定住了,因此你不能生產某品牌汽車外的其他”東西“,因而可以理解成使用抽象工廠模式不能新增新的”東西“(在簡單工廠和工廠方法中理論上都是可以新增任意”東西“的)。

簡單工廠

簡單工廠模式的工廠類一般是使用靜態方法,通過接收的參數的不同來返回不同的對象實例。不修改代碼的話,是無法擴展的。

簡單工廠

 簡單工廠代碼示例:

public interface Product{ 
   
} 
 public class ProductA implements Product{ 
  public ProductA(){ 
    System.out.println("生產ProductA ..."); 
  } 
} 

 public class ProductB implements Product{ 
  public ProductB(){ 
    System.out.println("生產ProductB ..."); 
  } 
} 
 public class ProductC implements Product{ 
	  public ProductC(){ 
	    System.out.println("生產ProductC ..."); 
	  } 
	} 
 public class SimpleFactory{ 
  public Product getProduct(String name){
	  if(name.equals("A")){
		  return new ProductA();
	  }
	  else if(name.equals("B")){
		  return new ProductB();
	  }
	  return new ProductC();
  }
} 
//測試類 
public class FactoryTest { 
  public static void main(String[] args) { 
    //廠商1負責生產產品A1、B1 
	SimpleFactory sf = new SimpleFactory(); 
    Product p1= sf.getProduct("A"); 
    Product p2 = sf.getProduct("B"); 
  } 
}

工廠方法

工廠方法是針對每一種產品提供一個工廠類。通過不同的工廠實例來創建不同的產品實例。在同一等級結構中,支持增加任意產品。

工廠方法

 工廠方法代碼示例:

public interface Product{       
}

public interface Creator{
       public Product factory();
}

public class ConcreteProduct1 implements Product{
       public ConcreteProduct1(){
              System.out.println("ConcreteProduct1被創建");
       }
}

public class ConcreteProduct2 implements Product{
       public ConcreteProduct2(){
              System.out.println("ConcreteProduct2被創建");
       }
 
}

public class ConcreteCreator1 implements Creator{
       public Product factory(){
              return new ConcreteProduct1();
       }
}

public class ConcreteCreator2 implements Creator{
       public Product factory(){
              return new ConcreteProduct2();
       }
}
 
public class FactoryTest{
       private static Creator creator1, creator2;
       private static Product prod1, prod2;

       public static void main(String[] args){
              creator1 = new ConcreteCreator1();
              prod1 = creator1.factory();
              System.out.println("----------------------------");
              creator2 = new ConcreteCreator2();
              prod2 = creator2.factory();
       }
}

抽象工廠

抽象工廠是應對產品族概念的。比如說,每個汽車公司可能要同時生產轎車,貨車,客車,那麼每一個工廠都要有創建轎車,貨車和客車的方法。

應對產品族概念而生,增加新的產品線很容易,但是無法增加新的產品。

抽象工廠

 抽象工廠代碼示例:

public interface IProductA{ 
  public void method(); 
} 

public interface IProductB{ 
  public void method(); 
} 

//由於已經設計好A1由廠商1生產,故以下輸出代碼有“廠商x” 
public class ProductA1 implements IProductA{ 
  public void method() { 
    System.out.println("廠商1    生產ProductA1 ..."); 
  } 
} 

public class ProductA2 implements IProductA{ 
  public void method() { 
    System.out.println("廠商2    生產ProductA2 ..."); 
  } 
} 

public class ProductB1 implements IProductB{ 
  public void method() { 
    System.out.println("廠商1    生產ProductB1 ..."); 
  } 
} 

public class ProductB2 implements IProductB{ 
  public void method() { 
    System.out.println("廠商2    生產ProductB2 ..."); 
  } 
} 

//不同的廠商負責自己牌子產品的生產 
public abstract class Factory1{ 
  abstract IProductA getProductA1(); 
  abstract IProductB getProductB1(); 
} 

public abstract class Factory2{ 
  abstract IProductA getProductA2(); 
  abstract IProductB getProductB2(); 
} 

//具體的工廠用來生產相關的產品 
public class ConcreteFactory1 extends Factory1{ 
  public IProductA getProductA1() { 
    return new ProductA1(); 
  } 
  public IProductB getProductB1() { 
    return new ProductB1(); 
  } 
} 

public class ConcreteFactoryB extends Factory2{ 
  public IProductA getProductA2() { 
    return new ProductA2(); 
  } 
  public IProductB getProductB2() { 
    return new ProductB2(); 
  } 
} 

//測試類 
public class FactoryTest { 
  public static void main(String[] args) { 
    //廠商1負責生產產品A1、B1 
    Factory1 factory1 = new ConcreteFactory1(); 
    IProductA productA1 = factory1.getProductA1(); 
    IProductB productB1 = factory1.getProductB1(); 
     
    productA1.method(); 
    productB1.method(); 
     
    //廠商2負責生產產品A2、B2 
    Factory2 factory2 = new ConcreteFactoryB(); 
    IProductA productA2 = factory2.getProductA2(); 
    IProductB productB2 = factory2.getProductB2(); 
     
    productA2.method(); 
    productB2.method(); 
  } 
}

三者的區別

簡單工廠 : 用來生產同一等級結構中的任意產品。(在遵循開閉原則的條件下,對於增加新的產品,無能爲力)。

工廠方法 :用來生產同一等級結構中的固定產品。(支持增加任意產品)   。
抽象工廠 :用來生產不同產品族的全部產品。(對於增加新的產品,無能爲力;支持增加產品族)  。


總結

工廠模式中,重要的是工廠類,而不是產品類。產品類可以是多種形式,多層繼承或者是單個類都是可以的。但要明確的,工廠模式的接口只會返回一種類型的實例,這是在設計產品類的時候需要注意的,最好是有父類或者共同實現的接口。使用工廠模式,返回的實例一定是工廠創建的,而不是從其他對象中獲取的。工廠模式返回的實例可以不是新創建的,返回由工廠創建好的實例也是可以的。


原文地址:http://blog.csdn.net/superbeck/article/details/4446177#comments

http://www.cnblogs.com/devinzhang/archive/2011/12/19/2293160.html

發佈了85 篇原創文章 · 獲贊 22 · 訪問量 66萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章