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 相关文章推荐
一个连接两个不同MYSQL数据库的PHP程序
Oct 09 PHP
如何提高MYSQL数据库的查询统计速度 select 索引应用
Apr 11 PHP
PHP编程过程中需要了解的this,self,parent的区别
Dec 30 PHP
php数组转换js数组操作及json_encode的用法详解
Oct 26 PHP
php中的filesystem文件系统函数介绍及使用示例
Feb 13 PHP
使用symfony命令创建项目的方法
Mar 17 PHP
php生成酷炫的四个字符验证码
Apr 22 PHP
PHP微信公众号自动发送红包API
Jun 01 PHP
PHP使用GD库输出汉字的方法【测试可用】
Nov 10 PHP
laravel model模型处理之修改查询或修改字段时的类型格式案例
Oct 17 PHP
使用Entrust扩展包在laravel 中实现RBAC的功能
Mar 16 PHP
PHP文件操作简单介绍及函数汇总
Dec 11 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
PHP5在Apache下的两种模式的安装
2006/09/05 PHP
WindowsXP中快速配置Apache+PHP5+Mysql
2008/06/05 PHP
队列在编程中的实际应用(php)
2010/09/04 PHP
浅析php中三个等号(===)和两个等号(==)的区别
2013/08/06 PHP
php 下载保存文件保存到本地的两种实现方法
2013/08/12 PHP
php判断用户是否手机访问代码
2015/06/08 PHP
基础的WordPress插件制作教程
2015/11/24 PHP
PHP测试框架PHPUnit组织测试操作示例
2018/05/28 PHP
php 自定义函数实现将数据 以excel 表格形式导出示例
2019/11/13 PHP
jQuery 第二课 操作包装集元素代码
2010/03/14 Javascript
基于jquery的实现简单的表格中增加或删除下一行
2010/08/01 Javascript
javascript查询字符串参数的方法
2015/01/28 Javascript
jquery实现根据浏览器窗口大小自动缩放图片的方法
2015/07/17 Javascript
jquery SweetAlert插件实现响应式提示框
2015/08/18 Javascript
JS简单随机数生成方法
2016/09/05 Javascript
javascript简易画板开发
2020/04/12 Javascript
jquery配合.NET实现点击指定绑定数据并且能够一键下载
2016/10/28 Javascript
JavaScript的数据类型转换原则(干货)
2018/03/15 Javascript
vue.js 2.*项目环境搭建、运行、打包发布的详细步骤
2019/05/01 Javascript
JavaScript中将值转换为字符串的五种方法总结
2019/06/06 Javascript
手把手15分钟搭一个企业级脚手架
2019/09/16 Javascript
解决vue-cli项目开发运行时内存暴涨卡死电脑问题
2019/10/29 Javascript
微信小程序12行js代码自己写个滑块功能(推荐)
2020/07/15 Javascript
JavaScript中如何调用Java方法
2020/09/16 Javascript
JS跨浏览器解析XML应用过程详解
2020/10/16 Javascript
Python实现SMTP发送邮件详细教程
2021/03/02 Python
python定时复制远程文件夹中所有文件
2019/04/30 Python
Django框架表单操作实例分析
2019/11/04 Python
简单整理HTML5的基本特性和语法
2016/02/18 HTML / CSS
Brookstone美国官网:独特新奇产品
2017/03/04 全球购物
文秘专业应届生求职信范文
2013/11/14 职场文书
2014年应届大学生毕业自我鉴定
2014/01/31 职场文书
党的群众路线教育实践活动个人对照检查材料
2014/09/22 职场文书
个人事迹材料怎么写
2014/12/30 职场文书
导游词之包公祠
2019/11/25 职场文书
一次SQL查询优化原理分析(900W+数据从17s到300ms)
2022/06/10 SQL Server