php 反射 简单工厂模式,php设计模式(七)使用反射来优化抽象工厂模式-Fun言

简单工厂的核心是 switch 或者 if 判断;

但是简单工厂配合抽象工厂的时候;

工厂里面的每个用来实例化产品的方法都需要 switch ;

这就显的重复了;

这时候我们可以使用反射来优化;

结构

多个 interface 或者 abstract 产品父类;

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

1个工厂;

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

示例

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

先创建 User 和 Article 产品 interface ;

User.php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithReflection;

/**

* User 产品接口

*

* Interface User

* @package Baijunyao\DesignPatterns\AbstractFactoryWithReflection

*/

interface User

{

/**

* 新增

*

* @return mixed

*/

public function insert();

/**

* 查询

*

* @return mixed

*/

public function select();

}

Article.php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithReflection;

/**

* Article 产品接口

*

* Interface Article

* @package Baijunyao\DesignPatterns\AbstractFactoryWithReflection

*/

interface Article

{

/**

* 新增

*

* @return mixed

*/

public function insert();

/**

* 查询

*

* @return mixed

*/

public function select();

}

然后创建对应的 MySQL 产品;

MySQLUser.php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithReflection;

/**

* 应用于 MySQL 的 User

*

* Class MySQLUser

* @package Baijunyao\DesignPatterns\AbstractFactoryWithReflection

*/

class MySQLUser implements User

{

/**

* 新增

*/

public function insert()

{

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

}

/**

* 查询

*/

public function select()

{

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

}

}

MySQLArticle.php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithReflection;

/**

* 应用于 MySQL 的 Article

*

* Class MySQLArticle

* @package Baijunyao\DesignPatterns\AbstractFactoryWithReflection

*/

class MySQLArticle implements Article

{

/**

* 新增

*/

public function insert()

{

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

}

/**

* 查询

*/

public function select()

{

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

}

}

然后创建对应的 SQLite 产品;

SQLiteUser.php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithReflection;

/**

* 适用于 SQLite 的 User

*

* Class SQLiteUser

* @package Baijunyao\DesignPatterns\AbstractFactoryWithReflection

*/

class SQLiteUser implements User

{

/**

* 新增

*/

public function insert()

{

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

}

/**

* 查询

*/

public function select()

{

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

}

}

SQLiteArticle.php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithReflection;

/**

* 适用于 SQLite 的 Article

*

* Class SQLiteArticle

* @package Baijunyao\DesignPatterns\AbstractFactoryWithReflection

*/

class SQLiteArticle implements Article

{

/**

* 新增

*

* @return mixed|void

*/

public function insert()

{

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

}

/**

* 查询

*

* @return mixed|void

*/

public function select()

{

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

}

}

产品部分没有什么变化;

配置项也一样;

config.php

return [

'driver' => 'MySQL'

];

核心就是反射部分;

Factory.php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithReflection;

use ReflectionClass;

use ReflectionException;

class Factory

{

/**

* 数据库

*

* @var string

*/

public $db = 'MySQL';

/**

* 产品类的命名空间

*

* @var string

*/

public $namespace = 'Baijunyao\DesignPatterns\AbstractFactoryWithReflection\\';

/**

* Factory constructor.

*/

public function __construct()

{

/**

* 从配置项中获取 driver

*/

$config = include 'config.php';

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

}

/**

* 创建 User 产品

*

* @return MySQLUser|SQLiteUser

*/

public function createUser()

{

$className = $this->namespace . $this->db . 'User';

try {

$class = new ReflectionClass($className);

$user = $class->newInstance();

} catch (ReflectionException $Exception) {

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

}

return $user;

}

/**

* 创建 Article 产品

*

* @return MySQLArticle|SQLiteArticle

*/

public function createArticle()

{

$className = $this->namespace . $this->db . 'Article';

try {

$class = new ReflectionClass($className);

$article = $class->newInstance();

} catch (ReflectionException $Exception) {

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

}

return $article;

}

}

运行;

index.php

namespace Baijunyao\DesignPatterns\AbstractFactoryWithReflection;

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

/**

* 客户端

*

* Class Client

* @package Baijunyao\DesignPatterns\AbstractFactoryWithReflection

*/

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();

当我们需要支持更多的数据库的时候;

比如说 PostgreSQL ;

我们只需要新建 PostgreSQLUser 和 PostgreSQLArticle ;

这就符合开闭原则了;

可以方便的扩展且不需要修改 createUser 方法;

over;

工厂相关的设计模式终于告一段落;

5b704d1096c90.jpg

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值