工廠模式主要是為創(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類圖:
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類圖:
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ō)明:
上面的類圖的產(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類圖:
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)