php 抽象工厂类实例,php设计模式(六)使用简单工厂来优化抽象工厂模式

抽象工厂模式中每增加一类产品都要改动全部的工厂;

这个工厂就是我们痛苦的源泉了;

这时候可以使用简单工厂来优化抽象工厂;

结构

多个 interface 或者 abstract 产品父类;

多个实现 interface 或者继承 abstract 的具体产品类;

1个工厂;

工厂类里面有多个方法分别实例化不同的具体产品类;

示例

产品部分跟抽象工厂是一样的;

先创建 User 和 Article 产品 interface ;

User.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory;

/**

* User 产品接口

*

* Interface User

* @package Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory

*/

interface User

{

/**

* 新增

*

* @return mixed

*/

public function insert();

/**

* 查询

*

* @return mixed

*/

public function select();

}

Article.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory;

/**

* Article 产品接口

*

* Interface Article

* @package Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory

*/

interface Article

{

/**

* 新增

*

* @return mixed

*/

public function insert();

/**

* 查询

*

* @return mixed

*/

public function select();

}

然后创建对应的 MySQL 产品;

MySQLUser.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory;

/**

* 应用于 MySQL 的 User

*

* Class MySQLUser

* @package Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory

*/

class MySQLUser implements User

{

/**

* 新增

*/

public function insert()

{

echo '向 MySQL 数据库中插入 User';

}

/**

* 查询

*/

public function select()

{

echo '从 MySQL 数据库中查询 User';

}

}

MySQLArticle.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory;

/**

* 应用于 MySQL 的 Article

*

* Class MySQLArticle

* @package Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory

*/

class MySQLArticle implements Article

{

/**

* 新增

*/

public function insert()

{

echo '向 MySQL 数据库中插入 Article';

}

/**

* 查询

*/

public function select()

{

echo '从 MySQL 数据库中查询 Article';

}

}

然后创建对应的 SQLite 产品;

SQLiteUser.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory;

/**

* 适用于 SQLite 的 User

*

* Class SQLiteUser

* @package Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory

*/

class SQLiteUser implements User

{

/**

* 新增

*/

public function insert()

{

echo '向SQLite数据库中插入 User';

}

/**

* 查询

*/

public function select()

{

echo '从SQLite数据库中查询 User';

}

}

SQLiteArticle.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory;

/**

* 适用于 SQLite 的 Article

*

* Class SQLiteArticle

* @package Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory

*/

class SQLiteArticle implements Article

{

/**

* 新增

*

* @return mixed|void

*/

public function insert()

{

echo '向 SQLite 数据库中插入 Article';

}

/**

* 查询

*

* @return mixed|void

*/

public function select()

{

echo '从 SQLite 数据库中查询 Article';

}

}

产品部分没有什么变化;

那工厂就是优化的关键了;

Factory.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory;

class Factory

{

public $db = 'MySQL';

/**

* 创建 User 产品

*

* @return MySQLUser|SQLiteUser

*/

public function createUser()

{

switch ($this->db) {

case 'MySQL':

$user = new MySQLUser();

break;

case 'SQLite':

$user = new SQLiteUser();

break;

default:

throw new \InvalidArgumentException('暂不支持的数据库类型');

}

return $user;

}

/**

* 创建 Article 产品

*

* @return MySQLArticle|SQLiteArticle

*/

public function createArticle()

{

switch ($this->db) {

case 'MySQL':

$article = new MySQLArticle();

break;

case 'SQLite':

$article = new SQLiteArticle();

break;

default:

throw new \InvalidArgumentException('暂不支持的数据库类型');

}

return $article;

}

}

运行;

index.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory;

require __DIR__.'/../vendor/autoload.php';

/**

* 客户端

*

* Class Client

* @package Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory

*/

class Client

{

/**

* 运行

*/

public function run()

{

$factory = new Factory();

// 创建 user

$user = $factory->createUser();

$user->insert();

echo '
';

$user->select();

echo '


';

// 创建 article

$article = $factory->createArticle();

$article->insert();

echo '
';

$article->select();

}

}

$client = new Client();

$client->run();

不过 Factory 中把 db 属性固定为 MySQL 了;

想换数据库类型还需要手动修改 db ;

我们还可以写个配置文件;

从配置文件中读取;

这样就不用改动 Factory 文件了;

config.php<?php

return [

'driver' => 'MySQL'

];

Factory.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithSimpleFactory;

class Factory

{

public $db = 'MySQL';

/**

* Factory constructor.

*/

public function __construct()

{

/**

* 从配置项中获取 driver

*/

$config = include 'config.php';

$this->db = $config['driver'];

}

/**

* 创建 User 产品

*

* @return MySQLUser|SQLiteUser

*/

public function createUser()

{

switch ($this->db) {

case 'MySQL':

$user = new MySQLUser();

break;

case 'SQLite':

$user = new SQLiteUser();

break;

default:

throw new \InvalidArgumentException('暂不支持的数据库类型');

}

return $user;

}

/**

* 创建 Article 产品

*

* @return MySQLArticle|SQLiteArticle

*/

public function createArticle()

{

switch ($this->db) {

case 'MySQL':

$article = new MySQLArticle();

break;

case 'SQLite':

$article = new SQLiteArticle();

break;

default:

throw new \InvalidArgumentException('暂不支持的数据库类型');

}

return $article;

}

}

虽然有了简单工厂可以少建一堆工厂了;

但是这里面的多个 switch 明显是有点重复的;

这呼吸起来还是有点痛;

下篇文章我们用反射优化抽象工厂进一步减轻这种痛;

999099f879071d31dd7884c6ecd3333d.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值