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程序员编程注意事项
Apr 10 PHP
PHP数组内存耗用太多问题的解决方法
Apr 05 PHP
PHP 循环列出目录内容的函数代码
May 26 PHP
php URL跳转代码 减少外链
Jun 25 PHP
php下利用curl判断远程文件是否存在的实现代码
Oct 08 PHP
php去除换行符的方法小结(PHP_EOL变量的使用)
Feb 16 PHP
php缓冲 output_buffering和ob_start使用介绍
Jan 30 PHP
thinkphp连贯操作实例分析
Nov 22 PHP
PHP中curl_setopt函数用法实例分析
Apr 16 PHP
yii2中使用Active Record模式的方法
Jan 09 PHP
Redis在Laravel项目中的应用实例详解
Aug 11 PHP
解决在laravel中auth建立时候遇到的问题
Oct 15 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
php 生成短网址原理及代码
2014/01/23 PHP
Yii+upload实现AJAX上传图片的方法
2016/07/13 PHP
PHP7多线程搭建教程
2017/04/21 PHP
关于PHP定时发送服务的解决办法
2017/04/23 PHP
Javascript中定义方法的另类写法(批量定义js对象的方法)
2011/02/25 Javascript
Jquery获取复选框被选中值的简单方法
2013/07/04 Javascript
你未必知道的JavaScript和CSS交互的5种方法
2014/04/02 Javascript
node.js中Socket.IO的进阶使用技巧
2014/11/04 Javascript
jfreechart插件将数据展示成饼状图、柱状图和折线图
2015/04/13 Javascript
浅谈DOM的操作以及性能优化问题-重绘重排
2017/01/08 Javascript
JavaScript限制在客户区可见范围的拖拽(解决scrollLeft和scrollTop的问题)(2)
2017/05/17 Javascript
JS中的JSON对象的定义和取值实现代码
2018/05/09 Javascript
Vue 应用中结合vux使用微信 jssdk的方法
2018/08/28 Javascript
微信小程序与后台PHP交互的方法实例分析
2018/12/10 Javascript
Vue动态组件与异步组件实例详解
2019/02/23 Javascript
jQuery+ajax实现批量删除功能完整示例
2019/06/06 jQuery
layui实现多图片上传并限制上传的图片数量
2019/09/26 Javascript
微信小程序自定义tabBar在uni-app的适配详解
2019/09/30 Javascript
6种JavaScript继承方式及优缺点(小结)
2020/02/06 Javascript
es6中let和const的使用方法详解
2020/02/24 Javascript
js实现电灯开关效果
2021/01/19 Javascript
Python备份Mysql脚本
2008/08/11 Python
使用python实现链表操作
2018/01/26 Python
Python3使用TCP编写一个简易的文件下载器功能
2019/05/08 Python
vscode 配置 python3开发环境的方法
2019/09/19 Python
使用python实现画AR模型时序图
2019/11/20 Python
解决python-docx打包之后找不到default.docx的问题
2020/02/13 Python
Python如何省略括号方法详解
2020/03/21 Python
Python+Appium实现自动化测试的使用步骤
2020/03/24 Python
基于Django signals 信号作用及用法详解
2020/03/28 Python
皇家阿尔伯特英国官方商店:Royal Albert骨瓷
2019/03/25 全球购物
Lentiamo丹麦:购买便宜的隐形眼镜
2021/01/13 全球购物
趣味运动会活动方案
2014/02/12 职场文书
仓库规划计划书
2014/04/28 职场文书
办公室禁烟通知
2015/04/23 职场文书
Python自动化工具之实现Excel转Markdown表格
2022/04/08 Python