設(shè)計(jì)模式(創(chuàng)建型)之工廠模式

工廠模式主要是為創(chuàng)建對(duì)象提供過(guò)渡接口,以便將創(chuàng)建對(duì)象的具體過(guò)程屏蔽隔離起來(lái),達(dá)到提高靈活性的目的。

創(chuàng)新互聯(lián)服務(wù)緊隨時(shí)代發(fā)展步伐,進(jìn)行技術(shù)革新和技術(shù)進(jìn)步,經(jīng)過(guò)10年的發(fā)展和積累,已經(jīng)匯集了一批資深網(wǎng)站策劃師、設(shè)計(jì)師、專業(yè)的網(wǎng)站實(shí)施團(tuán)隊(duì)以及高素質(zhì)售后服務(wù)人員,并且完全形成了一套成熟的業(yè)務(wù)流程,能夠完全依照客戶要求對(duì)網(wǎng)站進(jìn)行做網(wǎng)站、網(wǎng)站設(shè)計(jì)、建設(shè)、維護(hù)、更新和改版,實(shí)現(xiàn)客戶網(wǎng)站對(duì)外宣傳展示的首要目的,并為客戶企業(yè)品牌互聯(lián)網(wǎng)化提供全面的解決方案。

定義一個(gè)用于創(chuàng)建對(duì)象的接口,讓其子類來(lái)決定實(shí)例化哪一個(gè)類(產(chǎn)品),工廠方法使一個(gè)類的創(chuàng)建延遲到其子類中。

工廠模式分為三種:

    1)簡(jiǎn)單工廠模式(Simple Factory)
    2)工廠方法模式(Factory Method)
    3)抽象工廠模式(Abstract Factory)

 

一、簡(jiǎn)單工廠模式:

    簡(jiǎn)單工廠模式(Simple Factory)看為工廠方法模式(Factory Method)的一種特例,從接來(lái)下的實(shí)例可以看出。

    1、組成:
        1) 工廠類角色:這是本模式的核心,含有一定的商業(yè)邏輯和判斷邏輯。在java中它往往由一個(gè)具體類實(shí)現(xiàn)。
        2) 抽象產(chǎn)品角色:它一般是具體產(chǎn)品繼承的父類或者實(shí)現(xiàn)的接口。在java中由接口或者抽象類來(lái)實(shí)現(xiàn)。
        3) 具體產(chǎn)品角色:工廠類所創(chuàng)建的對(duì)象就是此角色的實(shí)例。在java中由一個(gè)具體類實(shí)現(xiàn)。

    2、UML類圖:

設(shè)計(jì)模式(創(chuàng)建型)之工廠模式

    3、相關(guān)代碼:

JAVA:

Factory .java:

// 工廠類角色

public class Factory {
 public static AbstractProduct getAnProduct( String s){
  if (s.equalsIgnoreCase("product1")){
   return new Product1();
  }else if(s.equalsIgnoreCase("product2")){
   return new Product2();
  }else{
   System.out.println("This type product is not exist in the factory!!!");
   return null;
  }
 }
}

 

AbstractProduct .java:

// 抽象產(chǎn)品角色

public interface AbstractProduct {
 public void doSomething();
}

 

Product1 .java:

// 具體產(chǎn)品角色

public class Product1 implements AbstractProduct {

 @Override
 public void doSomething() {
  // TODO Auto-generated method stub
  System.out.println("doSomething for Product1!!!");
 }

}

 

Product2 .java:

// 具體產(chǎn)品角色

public class Product2 implements AbstractProduct {

 @Override
 public void doSomething() {
  // TODO Auto-generated method stub
  System.out.println("doSomething for Product2!!!");
 }

}

 

testMain .java:

// 測(cè)試類

public class testMain {

 /**
  * @param args
  */
 public static void main(String[] args) {
  AbstractProduct p1 = Factory.getAnProduct("product1");
  p1.doSomething();
  AbstractProduct p2 = Factory.getAnProduct("product2");
  p2.doSomething();
  AbstractProduct p3 = Factory.getAnProduct("product1");
  p3.doSomething();
  AbstractProduct p4 = Factory.getAnProduct("product2");
  p4.doSomething();

 }

}

 

運(yùn)行結(jié)果:

doSomething for Product1!!!
doSomething for Product2!!!
doSomething for Product1!!!
doSomething for Product2!!!

 

C++:

 

//============================================================================
// Name        : SimpleFactory.cpp
// Author      :  Yan chao

// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
using namespace std;

// 抽象產(chǎn)品角色

class AbstractProduct{
public:
 AbstractProduct(){}
 virtual void doSomething() = 0;
 virtual ~AbstractProduct(){}
};

// 具體產(chǎn)品角色

class Product1 : public AbstractProduct{
public:
 void doSomething(){
  cout << "doSomething for Product1!!!" << endl;
 }
};

// 具體產(chǎn)品角色

class Product2 : public AbstractProduct{
public:
 void doSomething(){
  cout << "doSomething for Product2!!!" << endl;
 }
};

// 工廠類角色

class SimpleFactory{
public:
 static AbstractProduct* getProduct(string s){

  if ( s.compare("product1") == 0 ){
   cout << "s1:" << s << endl;
   return new Product1();
  }else if( s.compare("product2") == 0 ){
   cout << "s2:" << s << endl;
   return new Product2();
  }else{
   cout << "This type product is not exist in the factory!!!" << endl;
   return NULL;
  }
 }
};

int main() {
 SimpleFactory::getProduct("product1")->doSomething();
 SimpleFactory::getProduct("product2")->doSomething();
 SimpleFactory::getProduct("product2")->doSomething();
 return 0;
}

 

運(yùn)行結(jié)果:

s1:product1
doSomething for Product1!!!
s2:product2
doSomething for Product2!!!
s2:product2
doSomething for Product2!!!

 

    我們從開(kāi)閉原則(對(duì)擴(kuò)展開(kāi)放,對(duì)修改封閉)上來(lái)分析下簡(jiǎn)單工廠模式。當(dāng)我們想增加了一個(gè)產(chǎn)品的時(shí)候,只要符合抽象產(chǎn)品的規(guī)則,那么只要通知工廠類知道就可以被客戶使用了。所以對(duì)產(chǎn)品部分來(lái)說(shuō),它是符合開(kāi)閉原則的;但是工廠部分好像不太理想,因?yàn)槊吭黾右粋€(gè)產(chǎn)品,都要在工廠類中增加相應(yīng)的業(yè)務(wù)邏輯或者判斷邏輯,這顯然是違背開(kāi)閉原則的。可想而知對(duì)于新產(chǎn)品的加入,工廠類是很被動(dòng)的。對(duì)于這樣的工廠類,我們稱它為全能類或者上帝類。
    在實(shí)際應(yīng)用中,很可能產(chǎn)品是一個(gè)多層次的樹(shù)狀結(jié)構(gòu)。由于簡(jiǎn)單工廠模式中只有一個(gè)工廠類來(lái)對(duì)應(yīng)這些產(chǎn)品,所以這可能會(huì)把我們的上帝累壞了,也累壞了我們這些程序員。所以,就有了工廠方法模式!

二、工廠方法模式:

    工廠方法模式中,工廠類角色也抽象化了!這樣就有多個(gè)工廠類來(lái)分別對(duì)應(yīng)不同的產(chǎn)品了。

    1、組成:

        1) 抽象工廠角色: 這是工廠方法模式的核心,它與應(yīng)用程序無(wú)關(guān)。是具體工廠角色必須實(shí)現(xiàn)的接口或者必須繼承的父類。在java 中它由抽象類或者接口來(lái)實(shí)現(xiàn)。
        2) 具體工廠角色:它含有和具體業(yè)務(wù)邏輯有關(guān)的代碼。由應(yīng)用程序調(diào)用以創(chuàng)建對(duì)應(yīng)的具體產(chǎn)品的對(duì)象。
        3) 抽象產(chǎn)品角色:它是具體產(chǎn)品繼承的父類或者是實(shí)現(xiàn)的接口。在 java 中一般有抽象類或者接口來(lái)實(shí)現(xiàn)。
        4) 具體產(chǎn)品角色:具體工廠角色所創(chuàng)建的對(duì)象就是此角色的實(shí)例。在 java 中由具體的類
來(lái)實(shí)現(xiàn)。

    2、UML類圖:

設(shè)計(jì)模式(創(chuàng)建型)之工廠模式

    3、代碼實(shí)現(xiàn):

JAVA:

AbstractFactory .java:

// 抽象工廠角色

public abstract class AbstractFactory {
 abstract AbstractProduct getAnProduct();
}

 

AbstractProduct.java:

// 抽象產(chǎn)品角色

public interface AbstractProduct {
 public void doSomething();
}

 

Factory1.java:

// 具體工廠角色

public class Factory1 extends AbstractFactory {

 @Override
 AbstractProduct getAnProduct() {
  // TODO Auto-generated method stub
  return new Product1();
 }

}

 

Factory2.java:

// 具體工廠角色

public class Factory2 extends AbstractFactory {

 @Override
 AbstractProduct getAnProduct() {
  // TODO Auto-generated method stub
  return new Product2();
 }

}

 

Product1.java:

// 具體產(chǎn)品角色

public class Product1 implements AbstractProduct {

 public void doSomething() {
  // TODO Auto-generated method stub
  System.out.println("doSomething for Product1!!!");
 }

}

 

Product2.java:

// 具體產(chǎn)品角色

public class Product2 implements AbstractProduct {

 public void doSomething() {
  // TODO Auto-generated method stub
  System.out.println("doSomething for Product2!!!");
 }

}

 

testMain.java:

// 測(cè)試類

public class testMain {

 /**
  * @param args
  */
 public static void main(String[] args) {
  Factory1 fc1 = new Factory1();
  Factory2 fc2 = new Factory2();
  fc1.getAnProduct().doSomething();
  fc1.getAnProduct().doSomething();
  fc1.getAnProduct().doSomething();
  fc2.getAnProduct().doSomething();
  fc2.getAnProduct().doSomething();
  fc2.getAnProduct().doSomething();
  fc2.getAnProduct().doSomething();

 }

}

 

運(yùn)行結(jié)果:

doSomething for Product1!!!
doSomething for Product1!!!
doSomething for Product1!!!
doSomething for Product2!!!
doSomething for Product2!!!
doSomething for Product2!!!
doSomething for Product2!!!

 

C++:

//============================================================================
// Name        : Factory.cpp
// Author      :  Yan chao
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
using namespace std;

class AbstractProduct{
public:
 AbstractProduct(){}
 virtual void doSomething() = 0;
 virtual ~AbstractProduct(){}
};

class Product1 : public AbstractProduct{
public:
 void doSomething(){
  cout << "doSomething for Product1!!!" << endl;
 }
};

class Product2 : public AbstractProduct{
public:
 void doSomething(){
  cout << "doSomething for Product2!!!" << endl;
 }
};

class AbstractFactory {
public:
 virtual AbstractProduct* getProduct()=0;
 virtual ~AbstractFactory(){}
};

class Factory1 : public AbstractFactory{
public:
 Product1* getProduct(){
  return new Product1();
 }
};

class Factory2 : public AbstractFactory{
public:
 Product2* getProduct(){
  return new Product2();
 }
};

int main() {
 Factory1* f1 = new Factory1();
 Factory2* f2 = new Factory2();
 f1->getProduct()->doSomething();
 f1->getProduct()->doSomething();
 f1->getProduct()->doSomething();
 f2->getProduct()->doSomething();
 f2->getProduct()->doSomething();
 f2->getProduct()->doSomething();
 return 0;
}

 

運(yùn)行結(jié)果:

doSomething for Product1!!!
doSomething for Product1!!!
doSomething for Product1!!!
doSomething for Product2!!!
doSomething for Product2!!!
doSomething for Product2!!!

 

    可以看出工廠方法的加入,使得對(duì)象的數(shù)量成倍增長(zhǎng)。當(dāng)產(chǎn)品種類非常多時(shí),會(huì)出現(xiàn)大量的與之對(duì)應(yīng)的工廠對(duì)象,這不是我們所希望的。因?yàn)槿绻荒鼙苊膺@種情況,可以考慮使用簡(jiǎn)單工廠模式與工廠方法模式相結(jié)合的方式來(lái)減少工廠類:即對(duì)于產(chǎn)品樹(shù)上類似的種類(一般是樹(shù)的葉子中互為兄弟的)使用簡(jiǎn)單工廠模式來(lái)實(shí)現(xiàn)。

    簡(jiǎn)單工廠模式與工廠方法模式真正的避免了代碼的改動(dòng)了?沒(méi)有。在簡(jiǎn)單工廠模式中,新產(chǎn)品的加入要修改工廠角色中的判斷語(yǔ)句;而在工廠方法模式中,要么將判斷邏輯留在抽象工廠角色中,要么在客戶程序中將具體工廠角色寫死(就象上面的例子一樣)。而且產(chǎn)品對(duì)象創(chuàng)建條件的改變必然會(huì)引起工廠角色的修改。

三、抽象工廠模式:

    可以說(shuō),抽象工廠模式和工廠方法模式的區(qū)別就在于需要?jiǎng)?chuàng)建對(duì)象的復(fù)雜程度上。而且抽象工廠模式是三個(gè)里面最為抽象、最具一般性的。

    可以理解為,工廠方法模式中的產(chǎn)品是一維的,而抽象工廠模式中的產(chǎn)品的維度是多維的。(從下聯(lián)的類圖就可以看出來(lái)?。?/p>

    舉個(gè)具體的例子說(shuō)明:

設(shè)計(jì)模式(創(chuàng)建型)之工廠模式

        上面的類圖的產(chǎn)品類的分了兩個(gè)維度的實(shí)例。一個(gè)維度是,寶馬車和奔馳車;另一個(gè)維度是,商務(wù)型和運(yùn)動(dòng)型。

   1、 抽象工廠模式的用意為:給客戶端提供一個(gè)接口,可以創(chuàng)建多個(gè)產(chǎn)品中的產(chǎn)品對(duì)象。
    2、使用抽象工廠模式還要滿足一下條件:
        1) 系統(tǒng)中有多個(gè)產(chǎn)品族,而系統(tǒng)一次只可能消費(fèi)其中一族產(chǎn)品。
        2) 同屬于同一個(gè)產(chǎn)品族的產(chǎn)品以其使用。
   3、 組成(和工廠方法類一樣):

        1) 抽象工廠角色: 這是工廠方法模式的核心,它與應(yīng)用程序無(wú)關(guān)。是具體工廠角色必須實(shí)現(xiàn)的接口或者必須繼承的父類。在java 中它由抽象類或者接口來(lái)實(shí)現(xiàn)。
        2) 具體工廠角色:它含有和具體業(yè)務(wù)邏輯有關(guān)的代碼。由應(yīng)用程序調(diào)用以創(chuàng)建對(duì)應(yīng)的具體產(chǎn)品的對(duì)象。在java 中它由具體的類來(lái)實(shí)現(xiàn)。
        3) 抽象產(chǎn)品角色:它是具體產(chǎn)品繼承的父類或者是實(shí)現(xiàn)的接口。在 java 中一般有抽象類或者接口來(lái)實(shí)現(xiàn)。
        4) 具體產(chǎn)品角色:具體工廠角色所創(chuàng)建的對(duì)象就是此角色的實(shí)例。在 java 中由具體的類來(lái)實(shí)現(xiàn)。

    4、UML類圖:

設(shè)計(jì)模式(創(chuàng)建型)之工廠模式

    5、代碼實(shí)現(xiàn):

JAVA:

AbstractFactory.java:

// 抽象工廠角色

public abstract class AbstractFactory {
 abstract AbstractProductA getProductA();
 abstract AbstractProductB getProductB();
}

 

AbstractProductA.java:

// 抽象產(chǎn)品角色(A維度)

public interface AbstractProductA {
 public void doSomething();
}

 

AbstractProductB.java:

// 抽象產(chǎn)品角色(B維度)

public interface AbstractProductB {
 public void doSomething();
}

 

Factory1.java:

// 具體工廠角色

public class Factory1 extends AbstractFactory {

 @Override
 AbstractProductA getProductA() {
  // TODO Auto-generated method stub
  return new Product1A();
 }
 AbstractProductB getProductB() {
  // TODO Auto-generated method stub
  return new Product1B();
 }

}

 

Factory2.java:

// 具體工廠角色
public class Factory2 extends AbstractFactory {

 @Override
 AbstractProductA getProductA() {
  // TODO Auto-generated method stub
  return new Product2A();
 }

 AbstractProductB getProductB() {
  // TODO Auto-generated method stub
  return new Product2B();
 }

}

 

Product1A.java:

// 具體產(chǎn)品角色(A維度)

public class Product1A implements AbstractProductA {

 public void doSomething() {
  // TODO Auto-generated method stub
  System.out.println("doSomething for Product1A!!!");
 }

}

 

Product2A.java:

// 具體產(chǎn)品角色(A維度)

public class Product2A implements AbstractProductA {

 public void doSomething() {
  // TODO Auto-generated method stub
  System.out.println("doSomething for Product2A!!!");
 }

}

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Product1B.java:

// 具體產(chǎn)品角色(B維度)

public class Product1B implements AbstractProductB {

 public void doSomething() {
  // TODO Auto-generated method stub
  System.out.println("doSomething for Product1B!!!");
 }

}

Product2B.java:

// 具體產(chǎn)品角色(B維度)

public class Product2B implements AbstractProductB {

 public void doSomething() {
  // TODO Auto-generated method stub
  System.out.println("doSomething for Product2B!!!");
 }

}

 

testMain.java:

// 測(cè)試類

public class testMain {

 /**
  * @param args
  */
 public static void main(String[] args) {
  Factory1 fc1 = new Factory1();
  Factory2 fc2 = new Factory2();
  fc1.getProductA().doSomething();
  fc1.getProductB().doSomething();
  fc1.getProductA().doSomething();
  fc1.getProductB().doSomething();
  fc2.getProductA().doSomething();
  fc2.getProductB().doSomething();
  fc2.getProductA().doSomething();
  fc2.getProductB().doSomething();

 }

}

 

運(yùn)行結(jié)果:

doSomething for Product1A!!!
doSomething for Product1B!!!
doSomething for Product1A!!!
doSomething for Product1B!!!
doSomething for Product2A!!!
doSomething for Product2B!!!
doSomething for Product2A!!!
doSomething for Product2B!!!

名稱欄目:設(shè)計(jì)模式(創(chuàng)建型)之工廠模式
標(biāo)題URL:http://muchs.cn/article42/jcjsec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、網(wǎng)站建設(shè)App設(shè)計(jì)、品牌網(wǎng)站制作、域名注冊(cè)靜態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

綿陽(yáng)服務(wù)器托管