您好,登錄后才能下訂單哦!
工廠模式主要是為創建對象提供過渡接口,以便將創建對象的具體過程屏蔽隔離起來,達到提高靈活性的目的。
定義一個用于創建對象的接口,讓其子類來決定實例化哪一個類(產品),工廠方法使一個類的創建延遲到其子類中。
工廠模式分為三種:
1)簡單工廠模式(Simple Factory)
2)工廠方法模式(Factory Method)
3)抽象工廠模式(Abstract Factory)
一、簡單工廠模式:
簡單工廠模式(Simple Factory)看為工廠方法模式(Factory Method)的一種特例,從接來下的實例可以看出。
1、組成:
1) 工廠類角色:這是本模式的核心,含有一定的商業邏輯和判斷邏輯。在java中它往往由一個具體類實現。
2) 抽象產品角色:它一般是具體產品繼承的父類或者實現的接口。在java中由接口或者抽象類來實現。
3) 具體產品角色:工廠類所創建的對象就是此角色的實例。在java中由一個具體類實現。
2、UML類圖:
3、相關代碼:
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:
// 抽象產品角色
public interface AbstractProduct {
public void doSomething();
}
Product1 .java:
// 具體產品角色
public class Product1 implements AbstractProduct {
@Override
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("doSomething for Product1!!!");
}
}
Product2 .java:
// 具體產品角色
public class Product2 implements AbstractProduct {
@Override
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("doSomething for Product2!!!");
}
}
testMain .java:
// 測試類
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();
}
}
運行結果:
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;
// 抽象產品角色
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 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;
}
運行結果:
s1:product1
doSomething for Product1!!!
s2:product2
doSomething for Product2!!!
s2:product2
doSomething for Product2!!!
我們從開閉原則(對擴展開放,對修改封閉)上來分析下簡單工廠模式。當我們想增加了一個產品的時候,只要符合抽象產品的規則,那么只要通知工廠類知道就可以被客戶使用了。所以對產品部分來說,它是符合開閉原則的;但是工廠部分好像不太理想,因為每增加一個產品,都要在工廠類中增加相應的業務邏輯或者判斷邏輯,這顯然是違背開閉原則的。可想而知對于新產品的加入,工廠類是很被動的。對于這樣的工廠類,我們稱它為全能類或者上帝類。
在實際應用中,很可能產品是一個多層次的樹狀結構。由于簡單工廠模式中只有一個工廠類來對應這些產品,所以這可能會把我們的上帝累壞了,也累壞了我們這些程序員。所以,就有了工廠方法模式!
二、工廠方法模式:
工廠方法模式中,工廠類角色也抽象化了!這樣就有多個工廠類來分別對應不同的產品了。
1、組成:
1) 抽象工廠角色: 這是工廠方法模式的核心,它與應用程序無關。是具體工廠角色必須實現的接口或者必須繼承的父類。在java 中它由抽象類或者接口來實現。
2) 具體工廠角色:它含有和具體業務邏輯有關的代碼。由應用程序調用以創建對應的具體產品的對象。
3) 抽象產品角色:它是具體產品繼承的父類或者是實現的接口。在 java 中一般有抽象類或者接口來實現。
4) 具體產品角色:具體工廠角色所創建的對象就是此角色的實例。在 java 中由具體的類
來實現。
2、UML類圖:
3、代碼實現:
JAVA:
AbstractFactory .java:
// 抽象工廠角色
public abstract class AbstractFactory {
abstract AbstractProduct getAnProduct();
}
AbstractProduct.java:
// 抽象產品角色
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:
// 具體產品角色
public class Product1 implements AbstractProduct {
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("doSomething for Product1!!!");
}
}
Product2.java:
// 具體產品角色
public class Product2 implements AbstractProduct {
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("doSomething for Product2!!!");
}
}
testMain.java:
// 測試類
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();
}
}
運行結果:
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;
}
運行結果:
doSomething for Product1!!!
doSomething for Product1!!!
doSomething for Product1!!!
doSomething for Product2!!!
doSomething for Product2!!!
doSomething for Product2!!!
可以看出工廠方法的加入,使得對象的數量成倍增長。當產品種類非常多時,會出現大量的與之對應的工廠對象,這不是我們所希望的。因為如果不能避免這種情況,可以考慮使用簡單工廠模式與工廠方法模式相結合的方式來減少工廠類:即對于產品樹上類似的種類(一般是樹的葉子中互為兄弟的)使用簡單工廠模式來實現。
簡單工廠模式與工廠方法模式真正的避免了代碼的改動了?沒有。在簡單工廠模式中,新產品的加入要修改工廠角色中的判斷語句;而在工廠方法模式中,要么將判斷邏輯留在抽象工廠角色中,要么在客戶程序中將具體工廠角色寫死(就象上面的例子一樣)。而且產品對象創建條件的改變必然會引起工廠角色的修改。
三、抽象工廠模式:
可以說,抽象工廠模式和工廠方法模式的區別就在于需要創建對象的復雜程度上。而且抽象工廠模式是三個里面最為抽象、最具一般性的。
可以理解為,工廠方法模式中的產品是一維的,而抽象工廠模式中的產品的維度是多維的。(從下聯的類圖就可以看出來!)
舉個具體的例子說明:
上面的類圖的產品類的分了兩個維度的實例。一個維度是,寶馬車和奔馳車;另一個維度是,商務型和運動型。
1、 抽象工廠模式的用意為:給客戶端提供一個接口,可以創建多個產品族中的產品對象。
2、使用抽象工廠模式還要滿足一下條件:
1) 系統中有多個產品族,而系統一次只可能消費其中一族產品。
2) 同屬于同一個產品族的產品以其使用。
3、 組成(和工廠方法類一樣):
1) 抽象工廠角色: 這是工廠方法模式的核心,它與應用程序無關。是具體工廠角色必須實現的接口或者必須繼承的父類。在java 中它由抽象類或者接口來實現。
2) 具體工廠角色:它含有和具體業務邏輯有關的代碼。由應用程序調用以創建對應的具體產品的對象。在java 中它由具體的類來實現。
3) 抽象產品角色:它是具體產品繼承的父類或者是實現的接口。在 java 中一般有抽象類或者接口來實現。
4) 具體產品角色:具體工廠角色所創建的對象就是此角色的實例。在 java 中由具體的類來實現。
4、UML類圖:
5、代碼實現:
JAVA:
AbstractFactory.java:
// 抽象工廠角色
public abstract class AbstractFactory {
abstract AbstractProductA getProductA();
abstract AbstractProductB getProductB();
}
AbstractProductA.java:
// 抽象產品角色(A維度)
public interface AbstractProductA {
public void doSomething();
}
AbstractProductB.java:
// 抽象產品角色(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:
// 具體產品角色(A維度)
public class Product1A implements AbstractProductA {
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("doSomething for Product1A!!!");
}
}
Product2A.java:
// 具體產品角色(A維度)
public class Product2A implements AbstractProductA {
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("doSomething for Product2A!!!");
}
}
Product1B.java:
// 具體產品角色(B維度)
public class Product1B implements AbstractProductB {
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("doSomething for Product1B!!!");
}
}
Product2B.java:
// 具體產品角色(B維度)
public class Product2B implements AbstractProductB {
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("doSomething for Product2B!!!");
}
}
testMain.java:
// 測試類
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();
}
}
運行結果:
doSomething for Product1A!!!
doSomething for Product1B!!!
doSomething for Product1A!!!
doSomething for Product1B!!!
doSomething for Product2A!!!
doSomething for Product2B!!!
doSomething for Product2A!!!
doSomething for Product2B!!!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。