簡介
簡單工廠模式(Simple Factory Pattern)屬于類的建立型模式(但是簡單工廠模式不屬于23種設計模式之一),又叫靜态工廠方法模式(Static FactoryMethod Pattern), 是通過專門定義一個類來負責建立其他類的執行個體,這個類可以根據不同變量傳回不同類的産品執行個體。被建立的執行個體通常都具有共同的基類。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL4VFVOJTTU5EMNpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL4QDO2MzM0kTM1EzMwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
ProductA、ProductB 和 ProductC 繼承自Product抽象類,Show方法是不同産品的自描述;Factory依賴于ProductA、ProductB和ProductC。 Factory根據不同的條件 建立不同的Product 對象。
- 抽象(Product)産品:簡單工廠模式所建立的所有對象的父類,注意:這裡的父類可以是接口也可以是抽象類,它負責描述所有執行個體所共有的公共接口。
- 具體産品(Concrete Product):簡單工廠所建立的具體執行個體對象,這些具體的産品往往都擁有共同的父類。
- 工廠角色(Creator):這是簡單工廠模式的核心,由它負責建立所有的類的内部邏輯。當然工廠類必須能夠被外界調用,建立所需要的産品對象。
對于工廠模式,具體上可以分為三類:
- 簡單工廠模式;
- 工廠方法模式;
- 抽象工廠模式。
工廠模式有一種非常形象的描述,建立對象的類就如一個工廠,而需要被建立的對象就是一個個産品;在工廠中加工産品,使用産品的人,不用在乎産品是如何生産出來的。從軟體開發的角度來說,這樣就有效的降低了子產品之間的耦合。
簡單工廠模式深入分析:
簡單工廠模式解決的問題是:簡單工廠模式的核心思想就是:
- 如何去執行個體化一個合适的對象。
具體來說,把産品看着是一系列的類的集合,這些類是由某個抽象類或者接口派生出來的一個對象樹。而工廠類用來産生一個合适的對象來滿足客戶的要求。
- 有一個專門的類來負責建立執行個體的過程。
如果簡單工廠模式所涉及到的具體産品之間沒有共同的邏輯,那麼我們就可以使用接口來扮演抽象産品的角色;
如果具體産品之間有功能的邏輯,我們就必須把這些共同的東西提取出來,放在一個抽象類中,然後讓具體産品繼承抽象類。為實作更好複用的目的,共同的東西總是應該抽象出來的。
适用場合:
在程式中,需要建立的對象很多,導緻對象的new操作多且很複雜時,需要使用簡單工廠模式;
● 由于對象的建立過程是我們不需要去關心的,而我們注重的是對象的實際操作,是以,我們需要分離對象的建立和操作兩部分,如此,友善後期的程式擴充和維護。
代碼實作為:
#include<iostream>
using namespace std;
class Operation //抽象運算類
{
public:
double getA()
{
return m_numberA;
}
void setA(double value)
{
m_numberA = value;
}
double getB()
{
return m_numberB;
}
void setB(double value)
{
m_numberB = value;
}
virtual double getResult() = 0;
virtual ~Operation() = default;
protected:
Operation() {}
double m_numberA = 0;
double m_numberB = 0;
};
class OperationAdd : public Operation //加法類,繼承運算類
{
public:
double getResult()override
{
double result = m_numberA + m_numberB;
return result;
}
};
class OperationSub : public Operation //減法類,繼承運算類
{
public:
double getResult()override
{
double result = m_numberA - m_numberB;
return result;
}
};
class OperationMul : public Operation //乘法類,繼承運算類
{
public:
double getResult()override
{
double result = m_numberA * m_numberB;
return result;
}
};
class OperationDiv : public Operation //除法類,繼承運算類
{
public:
double getResult()override
{
double result = 0;
if (m_numberB != 0)
{
result = m_numberA / m_numberB;
}
else
{
return -1;
}
return result;
}
};
class OperationFactory //工廠類
{
public:
static Operation *createOperation(char type)
{
Operation *operation = nullptr;
switch (type)
{
case '+':
operation = new OperationAdd;
break;
case '-':
operation = new OperationSub;
break;
case '*':
operation = new OperationMul;
break;
case '/':
operation = new OperationDiv;
break;
}
return operation;
}
};
int main()
{
while (true)
{
cout << "\n請輸入第一個數進行計算:";
double strNumberA;
cin >> strNumberA;
cout << "\n請先輸入四則運算符号,進行相應的運算(+、-、*、/):\n" << endl;
char SignOfOperation = ' ';
while (cin >> SignOfOperation)
{
if (SignOfOperation == '+' || SignOfOperation == '-' || SignOfOperation == '*' || SignOfOperation == '/')
{
break;
}
else
{
cout << "請輸入正确運算符号,否則無法進行計算,請重新輸入:";
continue;
}
}
cout << "請輸入第二個數進行計算:";
double strNumberB;
cin >> strNumberB;
{
cout << "\n*************************************************************" << endl
<< "******************** 電腦基本功能展示. **********************" << endl
<< "*****************************************************************" << endl
<< "******************** 選擇1——進行加法. **********************" << endl
<< "******************** 選擇2——進行減法. **********************" << endl
<< "******************** 選擇3——進行乘法. **********************" << endl
<< "******************** 選擇4——進行除法. **********************" << endl
<< "******************** 選擇5——清屏. **********************" << endl
<< "******************** 選擇0——退出程式! **********************" << endl
<< "*****************************************************************" << endl;
}
cout << "\n******************** 請輸入你想要使用的電腦的序号 ***************" << endl;
cout << "請輸入你的選擇:";
int userChoice(0);
if (cin >> userChoice && userChoice == 0)
{
cout << "程式已退出,感謝您的使用!" << "\n" << endl;
break;
}
Operation* oper = nullptr;
switch (userChoice)
{
case 1:
oper = OperationFactory::createOperation(SignOfOperation);
oper->setA(strNumberA);
oper->setB(strNumberB);
cout << strNumberA << "+" << strNumberB << "=" << (oper->getResult()) << endl;
break;
case 2:
oper = OperationFactory::createOperation(SignOfOperation);
oper->setA(strNumberA);
oper->setB(strNumberB);
cout << strNumberA << "-" << strNumberB << "=" << (oper->getResult()) << endl;
break;
case 3:
oper = OperationFactory::createOperation(SignOfOperation);
oper->setA(strNumberA);
oper->setB(strNumberB);
cout << strNumberA << "*" << strNumberB << "=" << (oper->getResult()) << endl;
break;
case 4:
{
oper = OperationFactory::createOperation(SignOfOperation);
oper->setA(strNumberA);
oper->setB(strNumberB);
if (double temp = oper->getResult())
{
cout << strNumberA << "/" << strNumberB << "=" << temp << endl;
}
else
{
cout << "錯誤,除數不能為0!" << endl;
}
break;
}
case 5:
system("cls");
cout << "螢幕已經清屏,可以重新輸入!" << "\n" << endl;
break;
default:
cout << "輸入的序号不正确,請重新輸入!" << "\n" << endl;
}
delete oper;
oper = nullptr;
}
system("pause");
return 0;
}
簡單工廠模式的優缺點分析:
- 優點: 工廠類是整個模式的關鍵所在。它包含必要的判斷邏輯,能夠根據外界給定的資訊,決定究竟應該建立哪個具體類的對象。 使用者在使用時可以直接根據工廠類去建立 所需的執行個體,而無需了解這些對象是如何建立以及如何組織的。有利于整個軟體體系結構的優化。
- 缺點:由于工廠類集中了所有執行個體的建立邏輯,這就直接導緻一旦這個工廠出了問題,所有的用戶端都會受到牽連;而且由于簡單工廠模式的産品是基于一個共同的抽象類或者接口,這樣一來,一但産品的種類增加的時候,即有不同的産品接口或者抽象類的時候,工廠類就需要判斷何時建立何種種類的産品,這就和建立何種種類産品的産品互相混淆在了一起,違背了單一職責,導緻系統喪失靈活性和可維護性。
- 而且更重要的是: 簡單工廠模式違背了“開放封閉原則”,就是違背了“系統對擴充開放,對修改關閉”的原則,因為當我們新增加一個産品的時候必須修改工廠類,相應的工廠類就需要重新編譯一遍。
總結一下:
- 簡單工廠模式把産品的建立者和消費者分離,有利于軟體系統結構的優化;但是由于一切邏輯都集中在一個工廠類中,導緻了沒有很高的内聚性,同時也違背了“開放封閉原則”。
- 另外,簡單工廠模式的方法一般都是靜态的,而靜态工廠方法是無法讓子類繼承的,是以,簡單工廠模式無法形成基于基類的繼承樹結構。