资讯专栏INFORMATION COLUMN

PHP设计模式范例 — DesignPatternsPHP(1)创建型设计模式

lidashuang / 252人阅读

摘要:抽象工厂目的创建一系列相关或依赖的对象,而不指定它们的具体类。这个模式是一个真正的设计模式,因为它遵循了依赖反转原则众所周知这个代表了真正的面向对象程序设计。

【搬运于GitHub开源项目DesignPatternsPHP】
项目地址:戳我
1、创建型设计模式

在软件工程中,创建型设计模式承担着对象创建的职责,尝试创建适合程序上下文的对象,对象创建设计模式的产生是由于软件工程设计的问题,具体说是向设计中增加复杂度,创建型设计模式解决了程序设计中对象创建的问题。

1.1 抽象工厂 1.1.1 目的

创建一系列相关或依赖的对象,而不指定它们的具体类。通常创建的类都实现相同的接口。抽象工厂的客户端并不关心这些对象是如何创建的,它只知道它们是如何组合在一起的。

1.1.2 UML图

1.1.3 代码

你可以在 GitHub 上查看代码

Parser.php


CsvParser.php

skipHeaderLine = $skipHeaderLine;
    }

    public function parse(string $input): array
    {
        $headerWasParsed = false;
        $parsedLines = [];

        foreach (explode(PHP_EOL, $input) as $line) {
            if (!$headerWasParsed && $this->skipHeaderLine === self::OPTION_CONTAINS_HEADER) {
                $headerWasParsed = true;
                continue;
            }

            $parsedLines[] = str_getcsv($line);
        }

        return $parsedLines;
    }
}

JsonParser.php


ParserFactory.php


1.2 生成器模式
1.2.1 目的

生成器的目的是将复杂对象的创建过程(流程)进行抽象,生成器表现为接口的形式。

在特定的情况下,比如如果生成器对将要创建的对象有足够多的了解,那么代表生成器的接口 interface 可以是一个抽象类(也就是说可以有一定的具体实现,就像众所周知的适配器模式)。

如果对象有复杂的继承树,理论上创建对象的生成器也同样具有复杂的继承树。

提示:生成器通常具有流畅的接口,推荐阅读关于 PHPUnitmock 生成器获取更好的理解。
1.2.2 例子

PHPUnit: Mock 生成器

1.2.3 UML图

1.2.4 代码

你可以在 GitHub 上找到这些代码

Director.php

createVehicle();
        $builder->addDoors();
        $builder->addEngine();
        $builder->addWheel();

        return $builder->getVehicle();
    }
}

BuilderInterface.php


TruckBuilder.php

truck->setPart("rightDoor", new PartsDoor());
        $this->truck->setPart("leftDoor", new PartsDoor());
    }

    public function addEngine()
    {
        $this->truck->setPart("truckEngine", new PartsEngine());
    }

    public function addWheel()
    {
        $this->truck->setPart("wheel1", new PartsWheel());
        $this->truck->setPart("wheel2", new PartsWheel());
        $this->truck->setPart("wheel3", new PartsWheel());
        $this->truck->setPart("wheel4", new PartsWheel());
        $this->truck->setPart("wheel5", new PartsWheel());
        $this->truck->setPart("wheel6", new PartsWheel());
    }

    public function createVehicle()
    {
        $this->truck = new PartsTruck();
    }

    public function getVehicle(): Vehicle
    {
        return $this->truck;
    }
}

CarBuilder.php

car->setPart("rightDoor", new PartsDoor());
        $this->car->setPart("leftDoor", new PartsDoor());
        $this->car->setPart("trunkLid", new PartsDoor());
    }

    public function addEngine()
    {
        $this->car->setPart("engine", new PartsEngine());
    }

    public function addWheel()
    {
        $this->car->setPart("wheelLF", new PartsWheel());
        $this->car->setPart("wheelRF", new PartsWheel());
        $this->car->setPart("wheelLR", new PartsWheel());
        $this->car->setPart("wheelRR", new PartsWheel());
    }

    public function createVehicle()
    {
        $this->car = new PartsCar();
    }

    public function getVehicle(): Vehicle
    {
        return $this->car;
    }
}

Parts/Vehicle.php

data[$key] = $value;
    }
}

Parts/Truck.php


Parts/Car.php


Parts/Engine.php


Parts/Wheel.php


Parts/Door.php


1.3 工厂方法
1.3.1 目的

SimpleFactory的优点是您可以子类化它来实现创建对象的不同方法。

对于简单的情况,这个抽象类可能只是一个接口。

这个模式是一个 "真正" 的设计模式,因为它遵循了依赖反转原则 Dependency Inversion Principle 众所周知这个 "D" 代表了真正的面向对象程序设计。

它意味着工厂方法类依赖于类的抽象,而不是具体将被创建的类,这是工厂方法模式与简单工厂模式和静态工厂模式最重要的区别。

1.3.2 UML图

1.3.3 代码

你可以在 GitHub 上找到这些代码

Logger.php


StdoutLogger.php


FileLogger.php

filePath = $filePath;
    }

    public function log(string $message)
    {
        file_put_contents($this->filePath, $message . PHP_EOL, FILE_APPEND);
    }
}

LoggerFactory.php


StdoutLoggerFactory.php


FileLoggerFactory.php

filePath = $filePath;
    }

    public function createLogger(): Logger
    {
        return new FileLogger($this->filePath);
    }
}
1.4 多例

多例模式已经被考虑列入到反模式中!请使用依赖注入获得更好的代码可测试性和可控性!

1.4.1 目的

使类仅有一个命名的对象的集合可供使用,像单例模式但是有多个实例。

1.4.2 例子

2 个数据库连接,比如,一个连接MySQL,另一个连接SQLite

多个日志记录器(一个记录调试信息,另一个记录错误信息)

1.4.3 UML 图

1.4.4 代码

你可以在 GitHub 上找到这些代码

Multiton.php


1.5 对象池
1.5.1 目的

对象池设计模式 是创建型设计模式,它会对新创建的对象应用一系列的初始化操作,让对象保持立即可使用的状态 - 一个存放对象的 “池子” - 而不是对对象进行一次性的的使用(创建并使用,完成之后立即销毁)。对象池的使用者会对对象池发起请求,以期望获取一个对象,并使用获取到的对象进行一系列操作,当使用者对对象的使用完成之后,使用者会将由对象池的对象创建工厂创建的对象返回给对象池,而不是用完之后销毁获取到的对象。

对象池在某些情况下会带来重要的性能提升,比如耗费资源的对象初始化操作,实例化类的代价很高,但每次实例化的数量较少的情况下。对象池中将被创建的对象会在真正被使用时被提前创建,避免在使用时让使用者浪费对象创建所需的大量时间(比如在对象某些操作需要访问网络资源的情况下)从池子中取得对象的时间是可预测的,但新建一个实例所需的时间是不确定。

总之,对象池会为你节省宝贵的程序执行时间,比如像数据库连接,socket连接,大量耗费资源的代表数字资源的对象,像字体或者位图。不过,在特定情况下,简单的对象创建池(没有请求外部的资源,仅仅将自身保存在内存中)或许并不会提升效率和性能,这时候,就需要使用者酌情考虑了。

1.5.2 UML图

1.5.3 代码

你可以在 GitHub 上找到这些代码

WorkerPool.php

freeWorkers) == 0) {
            $worker = new StringReverseWorker();
        } else {
            $worker = array_pop($this->freeWorkers);
        }

        $this->occupiedWorkers[spl_object_hash($worker)] = $worker;

        return $worker;
    }

    public function dispose(StringReverseWorker $worker)
    {
        $key = spl_object_hash($worker);

        if (isset($this->occupiedWorkers[$key])) {
            unset($this->occupiedWorkers[$key]);
            $this->freeWorkers[$key] = $worker;
        }
    }

    public function count(): int
    {
        return count($this->occupiedWorkers) + count($this->freeWorkers);
    }
}

StringReverseWorker.php

createdAt = new DateTime();
    }

    public function run(string $text)
    {
        return strrev($text);
    }
}
1.6 原型模式 1.6.1 目的

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

1.6.2 例子

大量的数据对象(比如通过ORM获取1,000,000行数据库记录然后创建每一条记录对应的对象实体)

1.6.3 UML图

1.6.4 代码

你可以在 GitHub 上找到这些代码

BookPrototype.php

title;
    }

    public function setTitle($title)
    {
        $this->title = $title;
    }
}

BarBookPrototype.php


FooBookPrototype.php


1.7 简单工厂
1.7.1 目的

它与静态工厂不同,因为它不是静态的。因此,可以有多个参数化的工厂,可以子类化它,也可以模拟它。它总是比静态工厂更受欢迎!

1.7.2 UML图

1.7.3 代码

你可以在 GitHub 上找到这些代码

SimpleFactory.php


Bicycle.php


1.7.4 使用
 $factory = new SimpleFactory();
 $bicycle = $factory->createBicycle();
 $bicycle->driveTo("Paris");
1.8 单例模式 1.8.1 目标

使应用中只存在一个对象的实例,并且使这个单实例负责所有对该对象的调用。

1.8.2 例子

数据库连接器

日志记录器 (可能有多个实例,比如有多个日志文件因为不同的目的记录不同到的日志)

应用锁文件 (理论上整个应用只有一个锁文件)

1.8.3 UML图

1.8.4 代码

你可以在 GitHub 上找到这些代码

Singleton.php


1.9 静态工厂
1.9.1 目的

和抽象工厂类似,静态工厂模式用来创建一系列互相关联或依赖的对象,和抽象工厂模式不同的是静态工厂模式只用一个静态方法就解决了所有类型的对象创建,通常被命名为 Factory 或者 Generators

1.9.2 例子

Zend Framework: zend_cache_ 后端或 _Frontend 使用工厂方法创建缓存后端和前端

1.9.3 UML图

1.9.4 代码

你可以在 GitHub 上找到这些代码

StaticFactory.php


Formatter.php


FormatString.php


FormatNumber.php


相关文章:
PHP设计模式范例 — DesignPatternsPHP(2)结构型设计模式

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/29983.html

相关文章

  • PHP设计模式范例 — DesignPatternsPHP(2)结构设计模式

    摘要:此模式的主要特点是,与不同,其数据模式遵循单一职责原则。图代码你可以在上找到这些代码代理模式目的为昂贵或者无法复制的资源提供接口。图代码你可以在上找到这些代码相关文章设计模式范例创建型设计模式 【搬运于GitHub开源项目DesignPatternsPHP】 项目地址:戳我 2、结构型设计模式 在软件工程中,结构型设计模式集是用来抽象真实程序中的对象实体之间的关系,并使这种关系可被描...

    princekin 评论0 收藏0
  • 通俗易懂的设计模式

    摘要:面向对象设计模式通常以类别或对象来描述其中的关系和相互作用,但不涉及用来完成应用程序的特定类别或对象。里氏代换原则里氏代换原则是面向对象设计的基本原则之一。 通俗易懂的设计模式 零、使用 1、安装 2、测试 一、什么是设计模式 二、设计模式的类型 三、设计模式的六大原则 四、UML类图 1、看懂UML类图 2、解释 五、资料 前言:花了一些时间再次熟悉了一遍...

    wuyangnju 评论0 收藏0
  • C++ 开发 PHP 7 扩展之原生函数定义

    摘要:第一步打开项目下的文件,在文件中输入我们的函数的原型声明代码。这行代码注册一个原型为的函数,当这个函数被执行的时候,我们的函数将被运行时调用。原文地址开发扩展之原生函数定义 在上一篇中我们在hellozapi扩展中我们定义了几个常量,但是一个有用的扩展,必须得有函数,没有函数的扩展啥用没有,如果您觉得定义函数很难的话,您又错了,zendAPI就是为了让您生活变得美好而生的,而不会让事情...

    asce1885 评论0 收藏0
  • php实现设计模式】之服务定位器模式

    摘要:图示代码示例服务实例索引服务定义索引是否全局服务共享单例模式实例化省略服务实例化实现无法定位服务服务添加失败感谢文中图片来源来源网络 什么是服务定位器 服务定位器(service locator)他知道如何定位(创建或者获取)一个应用所需要的服务,服务使用者在实际使用中无需关心服务的实际实现。 有什么作用 实现服务使用者和服务的解耦,无需改变代码而只是通过简单配置更服服务实现。 UML...

    CarterLi 评论0 收藏0
  • 「真®全栈之路」Web前端开发的后端指南

    前言 在若干次前的一场面试,面试官看我做过python爬虫/后端 的工作,顺带问了我些后端相关的问题:你觉得什么是后端? 送命题。当时脑瓦特了,答曰:逻辑处理和数据增删改查。。。 showImg(https://user-gold-cdn.xitu.io/2019/4/24/16a4ed4fc8c18078); 当场被怼得体无完肤,羞愧难当。事后再反思这问题,结合资料总结了一下。发现自己学过的Re...

    chuyao 评论0 收藏0

发表评论

0条评论

lidashuang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<