在日常開發中,凡是需要生成復雜對象的地方,都可以嘗試考慮使用工廠模式來代替。
> 注意:上述復雜對象指的是類的構造函數參數過多等對類的構造有影響的情況,因為類的構造過于復雜,如果直接在其他業務類內使用,則兩者的耦合過重,后續業務更改,就需要在任何引用該類的源代碼內進行更改,光是查找所有依賴就很消耗時間了,更別說要一個一個修改了。
工廠模式的定義:定義一個創建產品對象的工廠接口,將產品對象的實際創建工作推遲到具體子工廠類當中。這滿足創建型模式中所要求的“創建與使用相分離”的特點。
按實際業務場景劃分,工廠模式有 3 種不同的實現方式,分別是簡單工廠模式、工廠方法模式和抽象工廠模式。
我們把被創建的對象稱為“產品”,把創建產品的對象稱為“工廠”。如果要創建的產品不多,只要一個工廠類就可以完成,這種模式叫“簡單工廠模式”。
在簡單工廠模式中創建實例的方法通常為靜態(static)方法,因此簡單工廠模式(Simple Factory Pattern)**又叫作靜態工廠方法模式**(Static Factory Method Pattern)。
簡單來說,簡單工廠模式有一個具體的工廠類,可以生成多個不同的產品,屬于創建型設計模式。簡單工廠模式不在 GoF 23 種設計模式之列。
簡單工廠模式每增加一個產品就要增加一個具體產品類和一個對應的具體工廠類,這增加了系統的復雜度,違背了“開閉原則”。
> “工廠方法模式”是對簡單工廠模式的進一步抽象化,其好處是可以使系統在不修改原來代碼的情況下引進新的產品,**即滿足開閉原則。**
## 優點和缺點
#### 優點:
1. 工廠類包含必要的邏輯判斷,可以決定在什么時候創建哪一個產品的實例。客戶端可以免除直接創建產品對象的職責,很方便的創建出相應的產品。工廠和產品的職責區分明確。
2. 客戶端無需知道所創建具體產品的類名,只需知道參數即可。
3. **也可以引入配置文件,在不修改客戶端代碼的情況下更換和添加新的具體產品類。**
#### 缺點:
1. 簡單工廠模式的工廠類單一,負責所有產品的創建,職責過重,一旦異常,整個系統將受影響。且工廠類代碼會非常臃腫,違背高聚合原則。
2. 使用簡單工廠模式會增加系統中類的個數(引入新的工廠類),增加系統的復雜度和理解難度
3. 系統擴展困難,一旦增加新產品不得不修改工廠邏輯,在產品類型較多時,可能造成邏輯過于復雜
4. 簡單工廠模式使用了 static 工廠方法,造成工廠角色無法形成基于繼承的等級結構。
#### 應用場景
對于產品種類相對較少的情況,考慮使用簡單工廠模式。使用簡單工廠模式的客戶端只需要傳入工廠類的參數,不需要關心如何創建對象的邏輯,可以很方便地創建所需產品。
## 模式的結構與實現
簡單工廠模式的主要角色如下:
* 簡單工廠(SimpleFactory):是簡單工廠模式的核心,負責實現創建所有實例的內部邏輯。工廠類的創建產品類的方法可以被外界直接調用,創建所需的產品對象。
* 抽象產品(Product):是簡單工廠創建的所有對象的父類,負責描述所有實例共有的公共接口。
* 具體產品(ConcreteProduct):是簡單工廠模式的創建目標。
```
<?php
namespace Factory\SimpleFactory;
class Circle implements IShape
{
public function draw()
{
return '畫一個圓形';
}
}
```
```
<?php
namespace Factory\SimpleFactory;
class Square implements IShape
{
public function draw()
{
return '畫一個正方形';
}
}
```
```
<?php
namespace Factory\SimpleFactory;
class ShapeFactory {
const CIRCLE = 'circle';
const SQUARE = 'square';
private $shape;
public function __construct($shape)
{
$this->shape = $shape;
}
public function getShape()
{
switch ($this->shape){
case self::CIRCLE:
return new Circle();
break;
case self::SQUARE:
return new Square();
break;
default:
return null;
}
}
}
```
```
<?php
/*
當增加或刪除形狀類時,工廠類也要做相應的修改,違反了開-閉原則。
*/
use Factory\SimpleFactory\ShapeFactory;
$shape = (new ShapeFactory(ShapeFactory::CIRCLE))->getShape();
$sting = $shape->draw();
echo $sting;
```
- 序言
- 從業感悟
- 常用名詞
- HTML
- JS
- ES6新特性
- jquery和vue對比
- 徹底理解this
- JQuery添加自定義函數
- js的實現
- 原始值和引用值
- MYSQL
- 簡介
- 術語
- 特點
- 范式
- 數據類型1
- 數據類型2
- 編碼
- 權限管理
- 事務
- mvvc
- 引擎
- MyISAM與InnoDB區別
- 索引類型
- 鎖
- 死鎖
- 分層架構
- 執行計劃
- join原理
- 高可用
- 日志類型
- 分庫分表
- 中間件
- 服務器
- 操作系統
- 信號量 鎖 隊列
- PHP
- composer加載原理
- composer基礎知識
- 自動加載函數
- composer加載代碼
- composer 自動加載
- 內存管理
- PHP執行流程
- cgi,fastCgi,php-fpm
- HTTP
- 錯誤碼
- 跨域請求
- 面試
- 安全
- HTTP劫持
- 設計模式
- 如何正確的使用設計模式
- 單例模式
- 原型模式
- 簡單工廠模式
- 工廠方法模式
- 抽象工廠模式
- 建造者模式
- 設計原則
- 算法
- PHP短標簽