在日常开发中,凡是需要生成复杂对象的地方,都可以尝试考虑使用工厂模式来代替。
> 注意:上述复杂对象指的是类的构造函数参数过多等对类的构造有影响的情况,因为类的构造过于复杂,如果直接在其他业务类内使用,则两者的耦合过重,后续业务更改,就需要在任何引用该类的源代码内进行更改,光是查找所有依赖就很消耗时间了,更别说要一个一个修改了。
工厂模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。
按实际业务场景划分,工厂模式有 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短标签