PHP设计模式之简单工厂和工厂模式实例分析


Posted in PHP onMarch 25, 2019

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

工厂模式是创建型模式的一种,分为简单工厂模式,工厂模式,抽象工厂模式,简单工厂可以称之为工厂模式的一个特例

先用一段简单的代码说明一下,现在假设我们是顾客,需要苹果味饮料和香蕉味饮料

<?php
class AppleDrink{
  function getDrinkName()
  {
    echo '苹果饮料';
  }
}
class BananaDrink{
  function getDrinkName()
  {
    echo '香蕉饮料';
  }
}
//顾客1
$apple = new AppleDrink();
$apple->getDrinkName();
echo "<br/>";
$banana = new BananaDrink();
$banana->getDrinkName();
echo "<br/>";
//顾客2
$apple1 = new AppleDrink();
$apple1->getDrinkName();
echo "<br/>";
$banana1 = new BananaDrink();
$banana1->getDrinkName();

运行结果:

苹果饮料
香蕉饮料
苹果饮料
香蕉饮料

这是最基本的写法,顾客和饮料是强耦合关系,也就是咱们平常说的硬编码

有一天,老板觉得AppleDrink这个名字在国内不好卖,想要改成Xingmu(醒目)这种接中国地气的名字(麦当劳改成金拱门)

你会发现,需要去代码中找到每一处NEW的地方,全部改成new Xingmu()

如果它还有其他的初始化步骤,就更是噩梦,很可能会引起一些不必要的麻烦

下面咱们用简单工厂模式,更改一下这个文件

<?php
class AppleDrink{
  function getDrinkName()
  {
    echo '苹果饮料';
  }
}
class BananaDrink{
  function getDrinkName()
  {
    echo '香蕉饮料';
  }
}
class FruitFactory{
  function makeDrink($fruit){
    if ($fruit == 'apple'){
      return new AppleDrink();
    }elseif ($fruit == 'banana'){
      return new BananaDrink();
    }
  }
}
$factory = new FruitFactory();
$apple = $factory->makeDrink('apple');
$apple->getDrinkName();
echo "<br/>";
$banana = $factory->makeDrink('banana');
$banana->getDrinkName();
echo "<br/>";
$apple1 = $factory->makeDrink('apple');
$apple1->getDrinkName();
echo "<br/>";
$banana1 = $factory->makeDrink('banana');
$banana1->getDrinkName();

运行结果:

苹果饮料
香蕉饮料
苹果饮料
香蕉饮料

现在我们发现,假如说老板想改名字,我只需要把FruitFactory里的new AppleDrink改为new Xingmu()即可,其他地方都不需要改动,也不用翻代码找哪些地方用new了,实现了顾客和饮料之间的解耦,也符合面向对象的设计思想,我只是想要一瓶饮料,我并不需要了解这个饮料是怎么制造出来的

这就是简单工厂模式,用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的,外界与具体类隔离开来,耦合性低,有利于整个软件体系结构的优化,适用于工厂类负责创建的对象比较少,客户只知道传入了工厂类的参数,对于如何创建对象(逻辑)不关心,简单工厂模式又叫静态工厂模式 可以把工厂类的方法写成静态方法 在不需要实例化工厂的前提下 直接调用静态方法 返回所需实例

好的,那么接下来,问题又来了,公司准备多元化产品,增加桔子味饮料,那么我们需要怎么做呢,首先要增加桔子味饮料类,然后需要在工厂里增加判断,当水果标识是orange的时候,返回桔子味饮料

class OrangeDrink{
  function getDrinkName()
  {
    echo '桔子味饮料';
  }
}
class FruitFactory{
  function makeDrink($fruit){
    if ($fruit == 'apple'){
      return new AppleDrink();
    }elseif ($fruit == 'banana'){
      return new BananaDrink();
    }elseif ($fruit == 'orange'){
      return new OrangeDrink();
    }
  }
}

然后当以后每次需要增加新的产品时,我们都需要更改工厂文件,当对象生成复杂的时候,这个工厂文件会越来越大,更改或许会引起一些意想不到的问题

面向对象的设计原则,对扩展开放,对更改关闭,那么有没有办法,在不更改原有代码的基础上,增加产品呢

答案是有的,咱们再改写一下这个方法

<?php
interface Drink{
  function getDrinkName();
}
class AppleDrink implements Drink{
  function getDrinkName()
  {
    echo '苹果味饮料';
  }
}
class BananaDrink implements Drink{
  function getDrinkName()
  {
    echo '香蕉味饮料';
  }
}
interface FruitFactory{
  function makeDrink();
}
class AppleFactory implements FruitFactory{
  function makeDrink()
  {
    return new AppleDrink();
  }
}
class BananaFactory implements FruitFactory{
  function makeDrink()
  {
    return new BananaDrink();
  }
}
$appleFactory = new AppleFactory();
$apple = $appleFactory->makeDrink();
$apple->getDrinkName();
echo "<br/>";
$bananaFactory = new BananaFactory();
$banana = $bananaFactory->makeDrink();
$banana->getDrinkName();

运行结果:

苹果味饮料
香蕉味饮料

现在当再次需要增加桔子味饮料时,只需要增加桔子味饮料产品和桔子味饮料工厂即可,不需要改动原来的代码

class OrangeDrink implements Drink{
  function getDrinkName()
  {
    echo '桔子味饮料';
  }
}
class OrangeFactory implements FruitFactory{
  function makeDrink()
  {
    return new OrangeDrink();
  }
}

这就是工厂模式,它是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现开闭原则,实现了对扩展开放,对更改关闭。其次实现更复杂的层次结构,可以应用于产品结果复杂的场合。工厂方法模式是对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。

 总结:

无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了

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

PHP 相关文章推荐
php GeoIP的使用教程
Mar 09 PHP
PHP之短标签开启设置
Jun 17 PHP
php实现12306余票查询、价格查询示例
Apr 17 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十一)
Jun 25 PHP
详谈PHP程序Laravel 5框架的优化技巧
Jul 18 PHP
PHP 接入支付宝即时到账功能
Sep 18 PHP
解决PHP程序运行时:Fatal error: Maximum execution time of 30 seconds exceeded in的错误提示
Nov 25 PHP
php实现和c#一致的DES加密解密实例
Jul 24 PHP
使用PHPStorm+XDebug搭建单步调试环境
Nov 19 PHP
PHP中检查isset()和!empty()函数的必要性
Feb 13 PHP
浅谈PHP各环境下的伪静态配置
Mar 13 PHP
thinkphp3.2框架中where条件查询用法总结
Aug 13 PHP
PHP实现无限极分类的两种方式示例【递归和引用方式】
Mar 25 #PHP
详解PHP神奇又有用的Trait
Mar 25 #PHP
PHP自动载入类文件函数__autoload的使用方法
Mar 25 #PHP
PHP生成短网址的思路以及实现方法的详解
Mar 25 #PHP
PHP错误提示It is not safe to rely on the system……的解决方法
Mar 25 #PHP
mongodb和php的用法详解
Mar 25 #PHP
PHP随机数函数rand()与mt_rand()的讲解
Mar 25 #PHP
You might like
利用文件属性结合Session实现在线人数统计
2006/10/09 PHP
详解php的魔术方法__get()和__set()使用介绍
2012/09/19 PHP
浅析PHP页面局部刷新功能的实现小结
2013/06/21 PHP
php实现按指定大小等比缩放生成上传图片缩略图的方法
2014/12/15 PHP
PHP 模拟登陆功能实例详解
2019/09/10 PHP
YII2框架使用控制台命令的方法分析
2020/03/18 PHP
基于jquery的超简单上下翻
2010/04/20 Javascript
jQuery在vs2008及js文件中的无智能提示的解决方法
2010/12/30 Javascript
基于jquery打造的百分比动态色彩条插件
2012/09/19 Javascript
提交表单时执行func方法实现代码
2013/03/17 Javascript
在页面上用action传递参数到后台出现乱码的解决方法
2013/12/31 Javascript
node.js入门教程迷你书、node.js入门web应用开发完全示例
2014/04/06 Javascript
两种方法基于jQuery实现IE浏览器兼容placeholder效果
2014/10/14 Javascript
jQuery的Scrollify插件实现滑动到页面下一节点
2015/07/05 Javascript
Angularjs中的ui-bootstrap的使用教程
2017/02/19 Javascript
JavaScript严格模式下关于this的几种指向详解
2017/07/12 Javascript
JS实现利用两个队列表示一个栈的方法
2017/12/13 Javascript
关于NodeJS中的循环引用详解
2019/07/23 NodeJs
微信小程序实现原生步骤条
2019/07/25 Javascript
JavaScript实现简单动态表格
2020/12/02 Javascript
浅谈Python浅拷贝、深拷贝及引用机制
2016/12/15 Python
python中的迭代和可迭代对象代码示例
2017/12/27 Python
Python面向对象之继承和组合用法实例分析
2018/08/27 Python
PyCharm+Qt Designer+PyUIC安装配置教程详解
2019/06/13 Python
Python 占位符的使用方法详解
2019/07/10 Python
python实点云分割k-means(sklearn)详解
2020/05/28 Python
CSS3旋转——彩色扇子兼容firefox浏览器
2013/06/04 HTML / CSS
加热夹克:RAVEAN
2018/10/19 全球购物
迪卡侬中国官网:Decathlon中国
2020/08/10 全球购物
意大利顶级奢侈品电商:LUISAVIAROMA(支持中文)
2020/05/26 全球购物
学雷锋演讲稿
2014/03/04 职场文书
协议书模板
2014/04/23 职场文书
环保口号大全
2014/06/12 职场文书
弘扬焦裕禄精神走群众路线思想汇报
2014/09/12 职场文书
优秀教师事迹材料
2014/12/15 职场文书
同事离别感言
2015/08/04 职场文书