200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > php 抽象工厂模式 php设计模式(五)抽象工厂模式

php 抽象工厂模式 php设计模式(五)抽象工厂模式

时间:2023-07-13 05:33:42

相关推荐

php 抽象工厂模式 php设计模式(五)抽象工厂模式

工厂方法有个问题是每个工厂只生产一个产品;

导致存在大量的工厂;

类比我们现实中的工厂;

生产牙刷造了一个牙刷厂;

生成鞋刷又造了一个鞋刷厂;

但是其实牙刷和鞋刷都属于刷子;

这就是产品族的概念了;

它们同属于一个产品族;

我们只造一个刷子厂同时生产一个产品族下的牙刷和鞋刷即可;

应用场景

要实例话的对象充满不确定性可能会改变的时候;

要创建的对象的数目和类型是未知的;

结构

多个 interface 或者 abstract 产品父类;

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

1个 interface 或者 abstract 工厂父类;

1个实现 interface 或者继承 abstract 的具体工厂类;

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

示例

先创建产品和工厂 interface ;

User.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactory;

/**

* User 产品接口

*

* Interface User

* @package Baijunyao\DesignPatterns\AbstractFactory

*/

interface User

{

/**

* 新增

*

* @return mixed

*/

public function insert();

/**

* 查询

*

* @return mixed

*/

public function select();

}

Factory.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactory;

/**

* 工厂接口

*

* Interface Factory

* @package Baijunyao\DesignPatterns\AbstractFactory

*/

interface Factory

{

/**

* 创建 User 产品

*

* @return mixed

*/

public function createUser();

}

然后分别创建对应的 MySQL 产品和工厂;

MySQLUser.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactory;

/**

* 应用于 MySQL 的 User

*

* Class MySQLUser

* @package Baijunyao\DesignPatterns\AbstractFactory

*/

class MySQLUser implements User

{

/**

* 新增

*/

public function insert()

{

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

}

/**

* 查询

*/

public function select()

{

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

}

}

MySQLFactory.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactory;

/**

* MySQL 工厂

*

* Class MySQLFactory

* @package Baijunyao\DesignPatterns\AbstractFactory

*/

class MySQLFactory implements Factory

{

/**

* 创建 MySQLUser 产品

*

* @return MySQLUser|mixed

*/

public function createUser()

{

return new MySQLUser();

}

}

运行

index.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactory;

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

/**

* 客户端

*

* Class Client

* @package Baijunyao\DesignPatterns\FactoryMethod

*/

class Client

{

/**

* 运行

*/

public function run()

{

// 使用 MySQL

$factory = new MySQLFactory();

$user = $factory->createUser();

$user->insert();

echo '

';

$user->select();

}

}

$client = new Client();

$client->run();

当我们只有一个产品的时候和工厂方法看起来没啥区别;

我们需要再增加一个产品组成产品族;

Article.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactory;

/**

* Article 产品接口

*

* Interface Article

* @package Baijunyao\DesignPatterns\AbstractFactory

*/

interface Article

{

/**

* 新增

*

* @return mixed

*/

public function insert();

/**

* 查询

*

* @return mixed

*/

public function select();

}

具体产品;

MySQLArticle.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactory;

/**

* 应用于 MySQL 的 Article

*

* Class MySQLArticle

* @package Baijunyao\DesignPatterns\AbstractFactory

*/

class MySQLArticle implements Article

{

/**

* 新增

*/

public function insert()

{

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

}

/**

* 查询

*/

public function select()

{

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

}

}

产品中现在我们有 User 和 Article 两个接口;

分别有 MySQLUser 和 MySQLArticle 两个具体产品类;

工厂中现在我们有 Factory 接口;

有 MySQLFactory 具体工厂类;

MySQLFactory 类中实现了实例化 MySQLUser 的方法;

工厂方法和抽象工厂之间一个巨大的差别就在于如何实例化 MySQLArticle 产品了;

如果我们再建一个工厂专门用来实例化 MySQLArticle 那就成了上篇文章的工厂方法了;

而我们的抽象工厂则是在 MySQLFactory 增加一个实例化 MySQLArticle 的方法;

先增加 interface 中的 createArticle 方法;

Factory.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactory;

/**

* 工厂接口

*

* Interface Factory

* @package Baijunyao\DesignPatterns\AbstractFactory

*/

interface Factory

{

/**

* 创建 User 产品

*

* @return mixed

*/

public function createUser();

/**

* 创建 Article 产品

*

* @return mixed

*/

public function createArticle();

}

再增加具体工厂中的方法;

MySQLFactory.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactory;

/**

* MySQL 工厂

*

* Class MySQLFactory

* @package Baijunyao\DesignPatterns\AbstractFactory

*/

class MySQLFactory implements Factory

{

/**

* 创建 MySQLUser 产品

*

* @return MySQLUser|mixed

*/

public function createUser()

{

return new MySQLUser();

}

/**

* 创建 MySQLArticle 产品

*

* @return MySQLArticle|mixed

*/

public function createArticle()

{

return new MySQLArticle();

}

}

运行

index.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactory;

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

/**

* 客户端

*

* Class Client

* @package Baijunyao\DesignPatterns\FactoryMethod

*/

class Client

{

/**

* 运行

*/

public function run()

{

// 使用 MySQL

$factory = new MySQLFactory();

// 创建 user

$user = $factory->createUser();

$user->insert();

echo '

';

$user->select();

echo '

';

$factory = new MySQLFactory();

// 创建 article

$article = $factory->createArticle();

$article->insert();

echo '

';

$article->select();

}

}

$client = new Client();

$client->run();

现在我们的系统已经支持 MySQL 了;

如果想支持 SQLite;

首先需要创建 SQLiteFactory ;

SQLiteFactory.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactory;

/**

* SQLite 工厂

*

* Class SQLiteFactory

* @package Baijunyao\DesignPatterns\AbstractFactory

*/

class SQLiteFactory implements Factory

{

/**

* 创建 SQLiteUser 产品

*

* @return SQLiteUser|mixed

*/

public function createUser()

{

return new SQLiteUser();

}

/**

* 创建 SQLiteArticle 产品

*

* @return SQLiteArticle|mixed

*/

public function createArticle()

{

return new SQLiteArticle();

}

}

分别创建 SQLiteUser 和 SQLiteArticle 产品;

SQLiteUser.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactory;

/**

* 适用于 SQLite 的 User

*

* Class SQLiteUser

* @package Baijunyao\DesignPatterns\AbstractFactory

*/

class SQLiteUser implements User

{

/**

* 新增

*/

public function insert()

{

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

}

/**

* 查询

*/

public function select()

{

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

}

}

SQLiteArticle.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactory;

/**

* 适用于 SQLite 的 Article

*

* Class SQLiteArticle

* @package Baijunyao\DesignPatterns\AbstractFactory

*/

class SQLiteArticle implements Article

{

/**

* 新增

*

* @return mixed|void

*/

public function insert()

{

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

}

/**

* 查询

*

* @return mixed|void

*/

public function select()

{

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

}

}

运行;

index.php<?php

namespace Baijunyao\DesignPatterns\AbstractFactory;

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

/**

* 客户端

*

* Class Client

* @package Baijunyao\DesignPatterns\FactoryMethod

*/

class Client

{

/**

* 运行

*/

public function run()

{

// 使用 MySQL

$factory = new MySQLFactory();

// 创建 user

$user = $factory->createUser();

$user->insert();

echo '

';

$user->select();

echo '

';

$factory = new MySQLFactory();

// 创建 article

$article = $factory->createArticle();

$article->insert();

echo '

';

$article->select();

echo '

';

// 使用 SQLite

$factory = new SQLiteFactory();

// 创建 user

$user = $factory->createUser();

$user->insert();

echo '

';

$user->select();

echo '

';

$factory = new SQLiteFactory();

// 创建 article

$article = $factory->createArticle();

$article->insert();

echo '

';

$article->select();

}

}

$client = new Client();

$client->run();

抽象工厂的优点是产品跟客户端完全分离;

我们在 Client 中只调用了 Factory;

甚至连产品的类名都不需要知道;

但是缺点也很明显;

那如果要增加一个 category 表;

那我们需要增加 Category接口类、MySQLCategory、SQLiteCategory;

还需要在 Factory、MySQLFactory、SQLiteFactory 中增加 createCategory 方法;

分别新增3个文件和改动3个文件才行;

对于聪(lan)明(duo)的程序猿来说;

这想想都是一种会呼吸的痛;

之前文章一直都在说设计模式之前是可以相互配合的;

下篇文章我们就用简单工厂配合抽象工厂来减轻这种痛苦;

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。