Design Pattern-Factory
===
# 工廠模式(Factory)
* 為一種創建模式
# 簡易工廠模式
* 優點 :
* 簡易好上手, 常與if/else或是switch case一同使用
* 缺點 :
* 如case過多維護不易,如新增類別還會動到其他程式
## 來製作肉品吧, 先從豬肉跟牛肉兩個開始做起, 於是先有抽象出了肉
```cpp=
class meat{
public:
meat(){};
~meat(){};
void virtual make() = 0;
void virtual info() = 0;
string name;
};
```
## 再來有了豬肉跟牛肉
```cpp=
class pork : public meat{
public:
void make() override{
cout << "A pound of pork is made." << endl;
name = "pork";
}
void info() override{
cout << "It is " << name << endl;
}
};
class beef : public meat{
public:
void make() override{
cout << "A pound of beef is made." << endl;
name = "beef";
}
void info() override{
cout << "It is " << name << endl;
}
};
```
## 於是建立了個簡易的工廠, 根據需要什麼肉就製作對應的肉品出來
* 簡易工廠模式如果產品越來越多會導致程式複雜化
* 試想你要一直維護一堆的if/else或是switch case光想就很複雜
* 也可以看到如果我在新增一個肌肉, Meat_Factory就需要再更動程式(違反OCP)
```cpp=
enum MEAT_CODE{
MEAT_PORK = 0,
MEAT_BEEF
};
class Meat_Factory{
public:
Meat_Factory(){};
~Meat_Factory(){};
std::shared_ptr<meat> make(MEAT_CODE type){
if(type==MEAT_PORK){
Meat = std::make_shared<pork>();
}else{
Meat = std::make_shared<beef>();
}
Meat->make();
return Meat;
}
private:
std::shared_ptr<meat> Meat = nullptr;
};
```
# 工廠模式
* 工廠方法模式定義了一個建立物件的介面,但由子類決定要實例化的類別為何。工廠方法讓類別把 實例化 的動作推遲到了子類。
* 優點 :
* 是一個高內聚的Design pattern
* 滿足了OCP及SRP
* 隱藏了創建對象的細節;使用者不用負擔細節,過多的細節增加了使用的成本
* 缺點 :
* 如果有新的子類會有更多工廠導致程式碼日益複雜,可能會有不易理解的抽象層出現
* 原本的工廠如要擴充不易變動(舉例 : 肉要切條或是切塊)
# Flow chart

## 接續肉類的案例,於是也將工廠抽象出來如下
```cpp=
class Factory{
public:
Factory(){};
virtual ~Factory(){}
virtual std::shared_ptr<meat> make() = 0;
};
```
## 並新增牛肉工廠跟豬肉工廠
```cpp=
class Pork_Factory : public Factory{
public:
std::shared_ptr<meat> make() override{
product = std::make_shared<pork>();
product->make();
return product;
}
private:
std::shared_ptr<meat> product = nullptr;
};
class Beef_Factory : public Factory{
public:
std::shared_ptr<meat> make() override{
product = std::make_shared<beef>();
product->make();
return product;
}
private:
std::shared_ptr<meat> product = nullptr;
};
```
## 今天我想要吃牛肉的話
* 創件一個Beef_Factory獲取牛肉吧
```cpp=
int main(){
// Simple Factory
// Meat_Factory meat_factory;
// meat_factory.make(MEAT_BEEF)->info();
// Factory
Beef_Factory beef_factory;
std::shared_ptr<meat> product = beef_factory.make();
product->info();
return 0;
}
```
# 抽象工廠
* 優點 :
* 可以確保產品之間可彼此相容
* 缺點 :
* 程式會隨著須混何的產品越來越複雜
* 可用於擴展產品不同的屬性, 舉例 :法師->會火焰的法師, 可頌->鹽味可頌
# Flow chart

## 消費者是懶惰的,想要有先切好的肉類所以多了"形狀"的要求
* 於是有了shape的類別且有塊狀跟條狀的shape
```cpp=
class shape{
public:
shape(){};
~shape(){};
string info;
void virtual make() = 0;
};
class stripe : public shape{
public:
void make() override{
cout << "Cut into stripe" << endl;
info = "stripe";
}
};
class cube : public shape{
public:
void make() override{
cout << "Cut into cube" << endl;
info = "cube";
}
};
```
## 於是工廠製作肉品就要選擇"肉的種類" 跟"形狀"
* 於是將工廠給抽象出來
```cpp=
class Abstract_Factory{
public:
virtual void make_meat() = 0;
virtual void make_shape() = 0;
std::shared_ptr<meat> meat_product;
std::shared_ptr<shape>shape_product;
};
```
* 今天我要一個切成塊狀的牛肉就可以實踐
```cpp=
class Cube_Beef_Factory : public Abstract_Factory{
public:
void make_meat(){
meat_product = std::make_shared<beef>();
meat_product->make();
}
void make_shape(){
shape_product = std::make_shared<cube>();
shape_product->make();
}
};
```
* 最後輸出
```cpp=
int main(){
Cube_Beef_Factory cube_beef;
cube_beef.make_meat();
cube_beef.make_shape();
cout << cube_beef.meat_product->name << endl;
cout << cube_beef.shape_product->info << endl;
return 0;
}
```
githun : https://github.com/GU-Lin/Design_Pattern_Practice/tree/main/Creational/Factory
source : https://refactoring.guru/design-patterns/factory-method
https://hypc-pub.github.io/design-patterns/patterns/factory-method-pattern.html
###### tags : `Creational` `DesignPattern`