PHP设计模式之工厂模式实例总结


Posted in PHP onSeptember 01, 2017

本文实例讲述了PHP设计模式之工厂模式。分享给大家供大家参考,具体如下:

使用工厂模式的目的或目标?

工厂模式的最大优点在于创建对象上面,就是把创建对象的过程封装起来,这样随时可以产生一个新的对象。

减少代码进行复制粘帖,耦合关系重,牵一发动其他部分代码。

通俗的说,以前创建一个对象要使用new,现在把这个过程封装起来了。

假设不使用工厂模式:那么很多地方调用类a,代码就会这样子创建一个实例:new a(),假设某天需要把a类的名称修改,意味着很多调用的代码都要修改。

工厂模式的优点就在创建对象上。

工厂模式的优点就在创建对象上。建立一个工厂(一个函数或一个类方法)来制造新的对象,它的任务就是把对象的创建过程都封装起来,

创建对象不是使用new的形式了。而是定义一个方法,用于创建对象实例。

每个类可能会需要连接数据库。那么就将连接数据库封装在一个类中。以后在其他类中通过类名:

为什么引入抽象的概念?

想一想,在现实生活中,当我们无法确定某个具体的东西的时候,往往把一类东西归于抽象类别。

工厂方法:

比如你的工厂叫做“香烟工厂”,那么可以有“七匹狼工厂”“中华工厂”等,但是,这个工厂只生厂一种商品:香烟;

抽象工厂:无法描述它到底生产什么产品,它生产很多类型的产品(所以抽象工厂就会生成子工厂)。

你的工厂是综合型的,是生产“一系列”产品,而不是“一个”,比如:生产“香烟”,还有“啤酒”等。然后它也可以有派生出来的具体的工厂,但这些工厂都是生产这一系列产品,只是可能因为地域不一样,为了适应当地人口味,味道也不太一样。

工厂模式:理解成只生成一种产品的工厂。比如生产香烟的。

工厂方法:工厂的一种产品生产线 。比如键盘的生成过程。

别人会反驳:吃饱了没事干,一定要修改类名称呢?这个说不定。一般都不会去修改类名称。

其实工厂模式有很多变体,抓住精髓才是关键:只要是可以根据不同的参数生成不同的类实例,那么就符合工厂模式的设计思想。

这样子让我联想到框架中经常会有负责生成具体类实例的方法供调用。

由于前面使用过phpcms,用phpcms的来帮助理解,更加好,如下:

pc_base:load_app_class("order"');//参数名称就是类名称。

将会生成得到order这个实例。传递不同的参数得到不同的类实例,这个就符合工厂模式。

pc_base:load_app_class("comment"');//生成一个comment类实例

当然load_app_class这个方法里面还会结合了单件模式的思想。避免调用n次,就重复创建n个相同的实例

工厂模式我想到的一个典型的应用就是:php可能要链接mysql,也可能要链接sqlserver,还有其他什么数据库。那么做一个抽象的数据库类,

这个类就是一个工厂类,专门负责产生不同的对象。

这样子做很方便扩展。我们在直接链接数据库的时候,不是使用代码

new Mysql($host,$username,$password,$dbname)

的形式

而可以动态生成一个连接数据库的实例。可以是mysql,也可以是连接oracle的。

class DbFactory
{
  function static factory($db_class_name)
  {
    $db_class_name = strtolower($db_class_name);
    if (include_once 'Drivers/' . $db_class_name . '.php') {
      $classname = 'Driver_' . $db_class_name;
      return new $db_class_name;
    } else {
      throw new Exception ('对应的数据库类没找到');
    } 
  }
}
DbFactory::factory("mysql");
DbFactory::factory("oracle");

在thinkphp框架中也有对应的实现:

Db.class.php就是一个工厂类(也可以叫做数据库中间层,之所以叫做中间层,是因为可以操作mysql、oracle等各数据库。而这个类就是中间层作用,屏蔽掉具体的实现。让程序员可以不改动原来的查询代码。中间层来对接mysql、oracle等数据库。

Db.class.php中有个factory()方法来创建不同的数据库实例

public function factory($db_config='') {
    // 读取数据库配置
    $db_config = $this->parseConfig($db_config);
    if(empty($db_config['dbms']))
      throw_exception(L('_NO_DB_CONFIG_'));
    // 数据库类型
    $this->dbType = ucwords(strtolower($db_config['dbms']));
    $class = 'Db'. $this->dbType;
    if(is_file(CORE_PATH.'Driver/Db/'.$class.'.class.php')) {
      // 内置驱动
      $path = CORE_PATH;
    }else{ // 扩展驱动
      $path = EXTEND_PATH;
    }
    // 检查驱动类
    if(require_cache($path.'Driver/Db/'.$class.'.class.php')) {
      $db = new $class($db_config);
      // 获取当前的数据库类型
      if( 'pdo' != strtolower($db_config['dbms']) )
        $db->dbType = strtoupper($this->dbType);
      else
        $db->dbType = $this->_getDsnType($db_config['dsn']);
      if(APP_DEBUG) $db->debug  = true;
    }else {
      // 类没有定义
      throw_exception(L('_NOT_SUPPORT_DB_').': ' . $db_config['dbms']);
    }
    return $db;
}

还有做支付接口的时候,未来可能对应不同的支付网关:支付宝、财付通、网银在线等。方便未来扩展,设计成工厂模式。定一个专门生产网关接口的工厂,抽象出来,做成接口形式,让所有的子类都要实现它的接口。以后加一个支付方式,要使用哪一种支付方式,改变一下参数即可。

书籍<php权威编程>(英文名称为PHP 5 Power Programming)也提到一个工厂模式的例子,学到一招:在为用户注册的时候,分为很多种角色的用户。比如册用户,匿名用户、管理员用户等。完全使用可以使用工厂的思想来实现,代码也容易维护,为每种角色可以生成操作的类。

定义以下几个类:

UserFactory 用户工厂类,负责生成不同的用户类
User:用户类的基类,所有用户类都是继承这个类
不同角色的类:注册用户类、匿名用户类、管理员用户类

总结结束,欢迎指正!

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
php处理斐波那契数列非递归方法
Feb 04 PHP
怎样给PHP源代码加密?PHP二进制加密与解密的解决办法
Apr 22 PHP
利用PHP将图片转换成base64编码的实现方法
Sep 13 PHP
php微信开发之自定义菜单实现
Nov 18 PHP
解决出现SoapFault (looks like we got no XML document)的问题
Jun 24 PHP
PHP输出Excel PHPExcel的方法
Jul 26 PHP
PHP htmlspecialchars()函数用法与实例讲解
Mar 08 PHP
PHP levenshtein()函数用法讲解
Mar 08 PHP
PHP5中使用mysqli的prepare操作数据库的介绍
Mar 18 PHP
PHP设计模式之数据访问对象模式(DAO)原理与用法实例分析
Dec 12 PHP
php使用pthreads v3多线程实现抓取新浪新闻信息操作示例
Feb 21 PHP
详解PHP用mb_string处理windows中文字符
May 26 PHP
浅谈关于PHP解决图片无损压缩的问题
Sep 01 #PHP
phpStudy配置多站点多域名和多端口的方法
Sep 01 #PHP
[原创]PHP获取数组表示的路径方法分析【数组转字符串】
Sep 01 #PHP
使用PHP连接数据库_实现用户数据的增删改查的整体操作示例
Sep 01 #PHP
php插件Xajax使用方法详解
Aug 31 #PHP
php数据库的增删改查 php与javascript之间的交互
Aug 31 #PHP
php注册系统和使用Xajax即时验证用户名是否被占用
Aug 31 #PHP
You might like
PHP strtok()函数的优点分析
2010/03/02 PHP
CodeIgniter扩展核心类实例详解
2016/01/20 PHP
PHP实现适用于文件内容操作的分页类
2016/06/15 PHP
用jQuery实现一些导航条切换,显示隐藏的实例代码
2013/06/08 Javascript
JavaScript 语言基础知识点总结(思维导图)
2013/11/10 Javascript
jQuery 1.9.1源码分析系列(十四)之常用jQuery工具
2015/12/02 Javascript
Bootstrap表单组件教程详解
2016/04/26 Javascript
JS控件bootstrap suggest plugin使用方法详解
2017/03/25 Javascript
Vue计算属性的使用
2017/08/04 Javascript
在vue-cli项目中使用bootstrap的方法示例
2018/04/21 Javascript
微信小程序实现折叠与展开文章功能
2018/06/12 Javascript
node链接mongodb数据库的方法详解【阿里云服务器环境ubuntu】
2019/03/07 Javascript
详解nodejs http请求相关总结
2019/03/31 NodeJs
arctext.js实现文字平滑弯曲弧形效果的插件
2019/05/13 Javascript
微信小程序如何调用新闻接口实现列表循环
2019/07/02 Javascript
[32:07]完美世界DOTA2联赛PWL S3 LBZS vs Rebirth 第一场 12.16
2020/12/17 DOTA
Python中多线程的创建及基本调用方法
2016/07/08 Python
Python中的id()函数指的什么
2017/10/17 Python
Python中property函数用法实例分析
2018/06/04 Python
解决pandas.DataFrame.fillna 填充Nan失败的问题
2018/11/06 Python
ActiveMQ:使用Python访问ActiveMQ的方法
2019/01/30 Python
Django使用uwsgi部署时的配置以及django日志文件的处理方法
2019/08/30 Python
python打开使用的方法
2019/09/30 Python
Sneaker Studio乌克兰:购买运动鞋
2018/03/26 全球购物
世界上第一个创建了罩杯系统的美国内衣品牌:Maidenform
2019/03/23 全球购物
三星俄罗斯授权在线商店:Samsung俄罗斯
2019/09/28 全球购物
精选鞋类、服装和配饰的全球领先目的地:Bodega
2021/02/27 全球购物
The North Face官方旗舰店:美国著名户外品牌
2020/09/28 全球购物
金融行业务员的自我评价
2013/12/13 职场文书
英语自我介绍演讲稿
2014/09/01 职场文书
基层党员群众路线教育实践活动个人对照检查材料思想汇报
2014/10/05 职场文书
毕业横幅标语
2014/10/08 职场文书
党的群众路线教育实践活动制度建设计划方案
2014/10/31 职场文书
2015年中职班主任工作总结
2015/05/25 职场文书
初中信息技术教学反思
2016/02/16 职场文书
利用 JavaScript 构建命令行应用
2021/11/17 Javascript