创建型模式主要是为了解决创建对象的时候的问题而存在的。

创建型设计模式有两个主导思想:一是将系统使用的具体类封装起来,二是隐藏这些具体类的实例创建和结合方式。

创建型模式主要分为以下五种:

  • 简单工厂模式(Simple Factory)和工厂方法模式(Factory method)
  • 抽象工厂模式(Abstract factory)
  • 单例模式(Singleton)
  • 建造者模式(Builder)
  • 原型模式(Prototype)

单例模式

单例模式的重点是,对象有且仅有一次实例化。
组成部分主要是:

  1. 私有化成员变量,存储实例化的对象
  2. 私有化构造方法,防止外部创建
  3. 私有化克隆方法,防止对象复制
  4. 公有的静态方法,对外界提供实例

上代码噻~

<?php
class Test{// 私有静态成员变量,保存全局实例private static $instance = NULL;// 私有构造方法,保证外界无法直接实例化private function __construct(){}// 防止克隆private function __clone(){}// 静态方法,返回此类唯一实例public static function getInstance(){if (!isset(self::$instance)) {self::$instance = new self();}return self::$instance;}
}

案例:
数据库连接

简单工厂模式

工厂模式:父类中提供一个创建对象的接口,用来允许子类决定实例化的类型

简单工厂模式:有抽象类,实现类,工厂类,把创建类这部分放在工厂类里面

<?php// 抽象类abstract class Math{abstract function getValue($x, $y){}}// 具体实现类class Add extends Math{public function getValue($x, $y) {return $x + $y;}}class Sub extends Math{public function getValue($x, $y) {return $x - $y;}}// 工厂类class MyMath{static function getClass($type) {switch ($type) {case "+":return new Add();case "-":return new Sub();}}}// 调用$myMath = MyMath::getClass("+");return $myMath->getValue(2, 3);

好处是调用简单, 创建对象和实例化分开,但是新增功能的时候需要修改工厂类,但是对其他部分代码不影响,定位问题也会更快。

工厂方法模式

封装类中不变的部分,提取善变的部分为独立类,通过依赖注入的方式达到解耦,复用和方便后期维护

  • 抽象工厂-------工艺的流程和顺序
  • 具体工厂-------隐藏背后产品的细节
  • 抽象产品-------产品生产工艺
  • 具体产品-------具体产品怎么生产,可以有个性化设置,只要工序按照抽象标准生产即可
<?php// 抽象类abstract class Math{abstract function getValue($x, $y){}}// 具体实现类1class Add extends Math{public function getValue($x, $y) {return $x + $y;}}// 具体实现类2class Sub extends Math{public function getValue($x, $y) {return $x - $y;}}// 抽象工厂类-和简单工厂方法最本质的区别就是创建对象的地方是抽出来的abstract class iFactory{abstract function getObj(){}}// 具体工厂类1class FactoryAdd extends iFactory{static function getObj(){return new Add();}}// 具体工厂类2class FactorySub extends iFactory{static function getObj(){return new Sub();}}// 具体调用。选择用哪个的过程交给客户端$client = FactoryAdd::getObj();return $client->getValue(2, 3);// 满足了开闭原则,但是可能会有很多类// 简单工厂更实用

应用例子:支付的话,支付宝支付,银行支付,微信支付。可以看作是一个典型的例子。
另一个例子就是PHP链接数据库的时候,不管是mysql还是sqlserver都抽象成同样的链接方式,查询方式,忽略底层不同的实现方式。

抽象工厂模式

产品类:<?php// 汽车(抽象产品接口)
interface AutoProduct
{public function dirve();
}//奥迪A4(具体产品类)
class AudiA4Product implements AutoProduct
{//获取汽车名称public function dirve(){echo "开奥迪A4"."<br>";}
}//奔驰C200(具体产品类)
class BenzC200Product implements AutoProduct
{//获取汽车名称public function dirve(){echo "开奔驰C200"."<br>";}
}//空调(抽象产品接口)
interface AirCondition
{public function blow();
}//格力空调某型号(具体产品类)
class GreeAirCondition implements AirCondition
{public function blow(){echo "吹格力空调某型号"."<br>";}
}//海尔空调某型号(具体产品类)
class HaierAirCondition implements AirCondition
{public function blow(){echo "吹海尔空调某型号"."<br>";}
}工厂类:
//工厂接口
interface Factory
{public function getAuto();public function getAirCondition();
}//工厂A = 奥迪A4 + 海尔空调某型号
class AFactory implements Factory
{//汽车public function getAuto(){return new AudiA4Product();}//空调public function getAirCondition(){return new HaierAirCondition();}
}//工厂B = 奔驰C200 + 格力空调某型号
class BFactory implements Factory
{//汽车public function getAuto(){return new BenzC200Product();}//空调public function getAirCondition(){return new GreeAirCondition();}
}//客户端测试代码
$factoryA = new AFactory();
$factoryB = new BFactory();//A工厂制作车
$auto_carA = $factoryA->getAuto();
$auto_airA = $factoryA->getAirCondition();//B工厂制作车
$auto_carB = $factoryB->getAuto();
$auto_airB = $factoryB->getAirCondition();//开奥迪车+吹海尔空调
$auto_carA->dirve();
$auto_airA->blow(); //热的时候可以吹吹空调//开奔驰车+吹格力空调;
$auto_carB->dirve();
$auto_airB->blow(); //热的时候可以吹吹空调?>

对比
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。

抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。

简单工厂 :用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)

建造者模式

定义了处理其他对象的复杂构建的对象设计
将一个复杂对象的建造和调用者分离。调用者只需要给出指定对象的类型和那天。
建造者模式负责按照顺序创建复杂的对象/
组成部分:

建造请求(Builder):定义一个抽象接口,规范产品各个组成成分的建造,包括建造方法和返回结果的方法
具体建造者(Concrete Builder):实现builder定义的方法,建造结束之后返回一个产品实例
指挥者角色(Director):调用具体的建造者角色建造那个产品,
产品角色(Product):在指挥者的指导下由具体建造者建造的那个复杂的对象
优点:
易于解耦,建造者模式可以很好的将一个对象的实现和相关业务逻辑分离,将产品本身和创建过程分类,可以使用相同的过程来创建不同的产品。
易于精确的控制对象,将负责对象的创建划分在不同的方法中,过程更加清晰
易于扩展,增加新的建造者无需修改原来的类库
缺点:
建造者模式的产品有较多的共同点,组成部分类似,如果产品之间差异较大则不适合,如果产品的内部变化复杂,需要定义更多的具体建造者来配合,导致系统变得庞大
建造者接口修改会导致所有执行类的修改
使用场景:
需要生成的产品对象有复杂的内部结构,属性相互依赖,建造者模式可以强迫生成顺序
在对象创建过程中会使用到系统的一些其他对象,这些对象在产品创建过程中不易得到

<?php// 抽象接口,定义装配汽车的流水线abstract class Builder{// 造轮子public abstract function buildWheel(){}// 造椅子public abstract function buildChair(){}// 造发电机public abstract function buildEngine(){}// 组装完成public abstract function getCar(){}}// 指挥类,用于指挥具体建造者工作,厂长安排工人装配class Director{public function assemble(Builder $builder) {$builder->buildChair();$builder->buildWheel();$builder->buildEngine();}}// 具体产品类class Car{private $buildList = [];// 加零件public function add($part) {$this->buildList[] = $part;}// 展示零件public function show() {foreach ($this->buildList as $key => $builder) {echo '组件' . $builder . '安装好了</br>';}print_r('组装完毕');}}// 具体建造者一号,用于建造普通汽车class ConcreteBuilder extends Builder{private $car;public function __construct() {$this->car = new Car();}public function buildChair() {$this->car->add('装椅子');}public function buildWheel() {$this->car->add('装轮子');}public function buildEngine() {$this->car->add('装引擎');}public function getCar(){return $this->car;}}// 具体建造者二号,用于建造好汽车class ConcreteBuilder2 extends Builder{private $car;public function __construct() {$this->car = new Car();}public function buildChair() {$this->car->add('装好椅子');}public function buildWheel() {$this->car->add('装好轮子');}public function buildEngine() {$this->car->add('装好引擎');}public function getCar(){return $this->car;}}// 客户端// 指挥者$director = new Director();// 具体建造者1$builder = new ConcretrBuilder();$director->assemble($builder);$car = $builder->getCar();// 具体建造者2$builder2 = new ConcretrBuilder2();$director->assemble($builder2);$car2 = $builder2->getCar();

原型模式

通过创建一个原型对象,然后复制原型对象来避免通过标准的方式(这里说的是new)创建大量的对象产生的开销。

代码:

<?phpabstract class CloneMe
{public $name;public $picture;abstract function __clone();
}class Person extends CloneMe
{public function __construct(){$this->picture = 'CloneMan.png';$this->name = 'Origin';public function display(){echo "<img src = $this->picture>";echo "<br/> $this->name<p/>";}function __clone(){}}
}// 调用:只需要实例化一次
$worker = new Person();
$worker->display();// 后续仅需要clone
$slacker = clone $worker;
$slacker->name = "Cloned";
$slacker->display();

有一个小的tips就是,克隆的时候并不会执行构造函数。

原型模式的优缺点
优点:
可以在运行时刻增加和删除产品
可以改变结构以指定新对象
可以改变值以指定新对象
减少子类的构造
用类动态配置应用
缺点:
每个类必须配一个克隆方法。
也就是说,当实例化的类是在运行时刻才知道的时候,比较适合原型模式。

PHP设计模式(2) -创建型模式相关推荐

  1. java设计模式中不属于创建型模式_23种设计模式第二篇:java工厂模式定义:工厂模式是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式...

    23种设计模式第二篇:java工厂模式 定义: 工厂模式是 Java 中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 工厂模式主要是为创建对象提供过渡接口, ...

  2. Java学习--设计模式之创建型模式

    一.简介 创建型模式:这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象.这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活.创建型模式包括:工 ...

  3. 备战面试日记(3.2) - (设计模式.23种设计模式之创建型模式)

    本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试. 记录日期:2022.1.6 大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习. 文章 ...

  4. 设计模式之创建型模式(工厂、原型、建造者)

    文章目录 创建型模式 2.1 工厂设计模式 2.1.1 简单工厂模式 2.1.2 工厂方法模式 2.1.3 抽象工厂 2.1.4 工厂模式总结 2.1.5 Spring中的工厂模式 2.1.6 工作中 ...

  5. GOF23设计模式(创建型模式)工厂模式

    目录: 一:工厂模式的核心本质 二:关于面向对象的六大基本原则 三:工厂模式的三大类详解(代码示例,详细分析) 首先,上咱本GOF23所有工厂模式的分类表格!!! 创建型模式 单例模式.工厂模式.抽象 ...

  6. 设计模式之创建型模式

    2019独角兽企业重金招聘Python工程师标准>>> 随着对软件工程研究的不断深入,设计模式也越来越多了,根据其目的准则,划分如下: 1. 创建型:creational 与对象的创 ...

  7. 设计模式6——创建型模式之原型模式

    定义:原型模式(Prototype Pattern),用原型模式指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 类型:创建型模式. 类图: 参与角色: CPrototype,抽象原型基类,提供 ...

  8. 设计模式1—创建型模式

    模式          在一定环境中解决某一问题的方案,包括三个基本元素--问题,解决方案和环境.          大白话:在一定环境下,用固定套路解决问题. 设计模式(Design pattern ...

  9. 创建型模式、结构型模式和行为型模式_设计模式之创建型模式

    设计模式GOF23(Group of Four) 设计模式可分为三种类型: 创建型模式:单例模式,工厂模式,抽象工厂模式,建造者模式,原型模式. 结构型模式:适配器模式,桥接模式,装饰模式,组合模式, ...

  10. GoF的23种设计模式之创建型模式的特点和分类

    创建型模式的主要关注点是"怎样创建对象?",它的主要特点是"将对象的创建与使用分离".这样可以降低系统的耦合度,使用者不需要关注对象的创建细节,对象的创建由相关 ...

最新文章

  1. 在SQL Server 2000 和SQL Server 2005中导出表结构
  2. mybatis 中case_mybatis 对string类型判断比较 group case when then 综合
  3. 关于 SAP Spartacus Loader Meta Reducer 的用途 - loading 在 true 和 false之前切换的逻辑
  4. 计算机c语言等级考试PDF,国家计算机等级考试c语言精华.pdf
  5. 产生式是蕴含式_独栋别墅~下沉式庭院设计
  6. SublimeText3.2.1的汉化方法(也适用于3)
  7. 《视觉SLAM十四讲》课后习题—ch3
  8. java排序算法学习(一)--冒泡排序
  9. debian:必须有官方源,难道国内镜像都是僵尸源?
  10. c语言傅立叶变换,傅立叶变换与傅立叶反变换的C语言实现
  11. 曾国藩论“慎独”:人生第一自强之道 寻乐之方
  12. 集合体系结构、Collection集合概述及常用方法(附迭代器遍历对象实例)、List(附子类LinkedList、ArrayList特点)、ListIterator、并发修改异常、增强for
  13. Hubble数据库x某股份制商业银行 信用卡反欺诈项目构建2.4亿条社交网络库
  14. PS-把长方形图片改为正方形图片
  15. 使用cmd命令窗口打开对应的应用程序
  16. 刘利刚-什么是计算机图形学?
  17. Java JSON字符串格式解析,数组取值
  18. java知识点博客园_Java知识点总结1
  19. CTF-NEFU校赛-题解
  20. Azure 进阶攻略 | 上云后的系统,「门禁」制度又该如何实现?

热门文章

  1. OpenCV信用卡识别
  2. 计算机网络之应用层与传输层
  3. Windows Phone 8.1中ScrollViewer(一)
  4. Android手机添加BusyBox超级终端打造linux工具箱
  5. 计算机产业、互联网造富的时代
  6. 你否有遇到Spring事务失效,花费太多时间找bug
  7. php微信开发查询分组,微信开发之用户组的介绍
  8. db2 EXPLAIN分析SQL
  9. Android数据持久化
  10. 如果你也有资料收集强迫症?