1、工厂模式
1.1、简介
工厂模式(Factory Pattern)是最常用的设计模式之一。
这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
我们在创建对象时,不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
1.2、优点
1、扩展性高,如果想增加一个产品,只要拓展一个工厂类就可以
2、易维护,如果一个类在多处代码中进行了new
,此时需要替换掉该类,或者该类改变了名字就会非常困难
3、一个调用者想创建一个对象,只要知道它的name即可
4、屏蔽产品的具体实现,调用者只关心产品的接口。
1.3、缺点
每次增加一个产品时,都需要增加一个具体类或对象实现工厂,让系统中的类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
2、例子
假设一个系统中有记录数据的需求;
根据情况需要有以下3种方式共同完成记录数据的需求:
1、使用MySQL记录数据
2、使用MongoDB记录数据
3、使用Redis记录数据
2.1、不使用工厂模式
步骤1
创建一个接口
IDb.php
interface IDatabase
{
function connect($host, $user, $passwd, $db);
//.....更多方法
}
步骤2
创建实现接口的实体类。
MySQL.php
class MySQL implements IDatabase
{
protected $conn;
function connect($host, $user, $passwd, $db)
{
//...假装这里是连接MySQL的相关代码
}
MongoDb.php
class MongoDb implements IDatabase
{
protected $conn;
function connect($host, $user, $passwd, $db)
{
//...假装这里是连接MongoDb的相关代码
}
Redis.php
class Redis implements IDatabase
{
protected $conn;
function connect($host, $user, $passwd, $db)
{
//...假装这里是连接redis的相关代码
}
步骤3
创建一个工厂,生成基于给定信息的实体类对象
DbFactory.php
class DbFactory
{
static function createDatabase($dbType)
{
$db = null;
if ($dbType === 'mysql'){
$db = new MySQL();
$db->connect();
}elseif($dbType === 'redis'){
$db = new Redis();
$db->connect();
}elseif($dbType === 'mongodb'){
$db = new MongoDb();
$db->connect();
}
return $db;
}
步骤 4
使用该工厂,通过传递类型信息来获取实体类的对象。
$db = DbFactory::createDatabase('redis')
//...数据查询或者修改、新增
参考:https://www.runoob.com/design-pattern/factory-pattern.html