摘要:抽象工廠目的創(chuàng)建一系列相關(guān)或依賴的對(duì)象,而不指定它們的具體類(lèi)。這個(gè)模式是一個(gè)真正的設(shè)計(jì)模式,因?yàn)樗裱艘蕾嚪崔D(zhuǎn)原則眾所周知這個(gè)代表了真正的面向?qū)ο蟪绦蛟O(shè)計(jì)。
【搬運(yùn)于GitHub開(kāi)源項(xiàng)目DesignPatternsPHP】
項(xiàng)目地址:戳我1、創(chuàng)建型設(shè)計(jì)模式
在軟件工程中,創(chuàng)建型設(shè)計(jì)模式承擔(dān)著對(duì)象創(chuàng)建的職責(zé),嘗試創(chuàng)建適合程序上下文的對(duì)象,對(duì)象創(chuàng)建設(shè)計(jì)模式的產(chǎn)生是由于軟件工程設(shè)計(jì)的問(wèn)題,具體說(shuō)是向設(shè)計(jì)中增加復(fù)雜度,創(chuàng)建型設(shè)計(jì)模式解決了程序設(shè)計(jì)中對(duì)象創(chuàng)建的問(wèn)題。
1.1 抽象工廠 1.1.1 目的創(chuàng)建一系列相關(guān)或依賴的對(duì)象,而不指定它們的具體類(lèi)。通常創(chuàng)建的類(lèi)都實(shí)現(xiàn)相同的接口。抽象工廠的客戶端并不關(guān)心這些對(duì)象是如何創(chuàng)建的,它只知道它們是如何組合在一起的。
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 目的生成器的目的是將復(fù)雜對(duì)象的創(chuàng)建過(guò)程(流程)進(jìn)行抽象,生成器表現(xiàn)為接口的形式。
在特定的情況下,比如如果生成器對(duì)將要?jiǎng)?chuàng)建的對(duì)象有足夠多的了解,那么代表生成器的接口 interface 可以是一個(gè)抽象類(lèi)(也就是說(shuō)可以有一定的具體實(shí)現(xiàn),就像眾所周知的適配器模式)。
如果對(duì)象有復(fù)雜的繼承樹(shù),理論上創(chuàng)建對(duì)象的生成器也同樣具有復(fù)雜的繼承樹(shù)。
提示:生成器通常具有流暢的接口,推薦閱讀關(guān)于 PHPUnit 的 mock 生成器獲取更好的理解。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的優(yōu)點(diǎn)是您可以子類(lèi)化它來(lái)實(shí)現(xiàn)創(chuàng)建對(duì)象的不同方法。
對(duì)于簡(jiǎn)單的情況,這個(gè)抽象類(lèi)可能只是一個(gè)接口。
這個(gè)模式是一個(gè) "真正" 的設(shè)計(jì)模式,因?yàn)樗裱艘蕾嚪崔D(zhuǎn)原則 Dependency Inversion Principle 眾所周知這個(gè) "D" 代表了真正的面向?qū)ο蟪绦蛟O(shè)計(jì)。
它意味著工廠方法類(lèi)依賴于類(lèi)的抽象,而不是具體將被創(chuàng)建的類(lèi),這是工廠方法模式與簡(jiǎn)單工廠模式和靜態(tài)工廠模式最重要的區(qū)別。
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 多例多例模式已經(jīng)被考慮列入到反模式中!請(qǐng)使用依賴注入獲得更好的代碼可測(cè)試性和可控性!
1.4.1 目的使類(lèi)僅有一個(gè)命名的對(duì)象的集合可供使用,像單例模式但是有多個(gè)實(shí)例。
1.4.2 例子2 個(gè)數(shù)據(jù)庫(kù)連接,比如,一個(gè)連接MySQL,另一個(gè)連接SQLite
多個(gè)日志記錄器(一個(gè)記錄調(diào)試信息,另一個(gè)記錄錯(cuò)誤信息)
1.4.3 UML 圖 1.4.4 代碼你可以在 GitHub 上找到這些代碼
Multiton.php
1.5 對(duì)象池 1.5.1 目的對(duì)象池設(shè)計(jì)模式 是創(chuàng)建型設(shè)計(jì)模式,它會(huì)對(duì)新創(chuàng)建的對(duì)象應(yīng)用一系列的初始化操作,讓對(duì)象保持立即可使用的狀態(tài) - 一個(gè)存放對(duì)象的 “池子” - 而不是對(duì)對(duì)象進(jìn)行一次性的的使用(創(chuàng)建并使用,完成之后立即銷(xiāo)毀)。對(duì)象池的使用者會(huì)對(duì)對(duì)象池發(fā)起請(qǐng)求,以期望獲取一個(gè)對(duì)象,并使用獲取到的對(duì)象進(jìn)行一系列操作,當(dāng)使用者對(duì)對(duì)象的使用完成之后,使用者會(huì)將由對(duì)象池的對(duì)象創(chuàng)建工廠創(chuàng)建的對(duì)象返回給對(duì)象池,而不是用完之后銷(xiāo)毀獲取到的對(duì)象。
對(duì)象池在某些情況下會(huì)帶來(lái)重要的性能提升,比如耗費(fèi)資源的對(duì)象初始化操作,實(shí)例化類(lèi)的代價(jià)很高,但每次實(shí)例化的數(shù)量較少的情況下。對(duì)象池中將被創(chuàng)建的對(duì)象會(huì)在真正被使用時(shí)被提前創(chuàng)建,避免在使用時(shí)讓使用者浪費(fèi)對(duì)象創(chuàng)建所需的大量時(shí)間(比如在對(duì)象某些操作需要訪問(wèn)網(wǎng)絡(luò)資源的情況下)從池子中取得對(duì)象的時(shí)間是可預(yù)測(cè)的,但新建一個(gè)實(shí)例所需的時(shí)間是不確定。
總之,對(duì)象池會(huì)為你節(jié)省寶貴的程序執(zhí)行時(shí)間,比如像數(shù)據(jù)庫(kù)連接,socket連接,大量耗費(fèi)資源的代表數(shù)字資源的對(duì)象,像字體或者位圖。不過(guò),在特定情況下,簡(jiǎn)單的對(duì)象創(chuàng)建池(沒(méi)有請(qǐng)求外部的資源,僅僅將自身保存在內(nèi)存中)或許并不會(huì)提升效率和性能,這時(shí)候,就需要使用者酌情考慮了。
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 目的通過(guò)創(chuàng)建一個(gè)原型對(duì)象,然后復(fù)制原型對(duì)象來(lái)避免通過(guò)標(biāo)準(zhǔn)的方式創(chuàng)建大量的對(duì)象產(chǎn)生的開(kāi)銷(xiāo)(new Foo())。
1.6.2 例子大量的數(shù)據(jù)對(duì)象(比如通過(guò)ORM獲取1,000,000行數(shù)據(jù)庫(kù)記錄然后創(chuàng)建每一條記錄對(duì)應(yīng)的對(duì)象實(shí)體)
1.6.3 UML圖 1.6.4 代碼你可以在 GitHub 上找到這些代碼
BookPrototype.php
title; } public function setTitle($title) { $this->title = $title; } }BarBookPrototype.php
FooBookPrototype.php
1.7 簡(jiǎn)單工廠 1.7.1 目的它與靜態(tài)工廠不同,因?yàn)樗皇庆o態(tài)的。因此,可以有多個(gè)參數(shù)化的工廠,可以子類(lèi)化它,也可以模擬它。它總是比靜態(tài)工廠更受歡迎!
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 目標(biāo)使應(yīng)用中只存在一個(gè)對(duì)象的實(shí)例,并且使這個(gè)單實(shí)例負(fù)責(zé)所有對(duì)該對(duì)象的調(diào)用。
1.8.2 例子數(shù)據(jù)庫(kù)連接器
日志記錄器 (可能有多個(gè)實(shí)例,比如有多個(gè)日志文件因?yàn)椴煌哪康挠涗洸煌降娜罩荆?/p>
應(yīng)用鎖文件 (理論上整個(gè)應(yīng)用只有一個(gè)鎖文件)
1.8.3 UML圖 1.8.4 代碼你可以在 GitHub 上找到這些代碼
Singleton.php
1.9 靜態(tài)工廠 1.9.1 目的和抽象工廠類(lèi)似,靜態(tài)工廠模式用來(lái)創(chuàng)建一系列互相關(guān)聯(lián)或依賴的對(duì)象,和抽象工廠模式不同的是靜態(tài)工廠模式只用一個(gè)靜態(tài)方法就解決了所有類(lèi)型的對(duì)象創(chuàng)建,通常被命名為 Factory 或者 Generators
1.9.2 例子Zend Framework: zend_cache_ 后端或 _Frontend 使用工廠方法創(chuàng)建緩存后端和前端
1.9.3 UML圖 1.9.4 代碼你可以在 GitHub 上找到這些代碼
StaticFactory.php
Formatter.php
FormatString.php
FormatNumber.php
相關(guān)文章:
PHP設(shè)計(jì)模式范例 — DesignPatternsPHP(2)結(jié)構(gòu)型設(shè)計(jì)模式
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/29983.html
摘要:此模式的主要特點(diǎn)是,與不同,其數(shù)據(jù)模式遵循單一職責(zé)原則。圖代碼你可以在上找到這些代碼代理模式目的為昂貴或者無(wú)法復(fù)制的資源提供接口。圖代碼你可以在上找到這些代碼相關(guān)文章設(shè)計(jì)模式范例創(chuàng)建型設(shè)計(jì)模式 【搬運(yùn)于GitHub開(kāi)源項(xiàng)目DesignPatternsPHP】 項(xiàng)目地址:戳我 2、結(jié)構(gòu)型設(shè)計(jì)模式 在軟件工程中,結(jié)構(gòu)型設(shè)計(jì)模式集是用來(lái)抽象真實(shí)程序中的對(duì)象實(shí)體之間的關(guān)系,并使這種關(guān)系可被描...
摘要:面向?qū)ο笤O(shè)計(jì)模式通常以類(lèi)別或?qū)ο髞?lái)描述其中的關(guān)系和相互作用,但不涉及用來(lái)完成應(yīng)用程序的特定類(lèi)別或?qū)ο蟆@锸洗鷵Q原則里氏代換原則是面向?qū)ο笤O(shè)計(jì)的基本原則之一。 通俗易懂的設(shè)計(jì)模式 零、使用 1、安裝 2、測(cè)試 一、什么是設(shè)計(jì)模式 二、設(shè)計(jì)模式的類(lèi)型 三、設(shè)計(jì)模式的六大原則 四、UML類(lèi)圖 1、看懂UML類(lèi)圖 2、解釋 五、資料 前言:花了一些時(shí)間再次熟悉了一遍...
摘要:第一步打開(kāi)項(xiàng)目下的文件,在文件中輸入我們的函數(shù)的原型聲明代碼。這行代碼注冊(cè)一個(gè)原型為的函數(shù),當(dāng)這個(gè)函數(shù)被執(zhí)行的時(shí)候,我們的函數(shù)將被運(yùn)行時(shí)調(diào)用。原文地址開(kāi)發(fā)擴(kuò)展之原生函數(shù)定義 在上一篇中我們?cè)趆ellozapi擴(kuò)展中我們定義了幾個(gè)常量,但是一個(gè)有用的擴(kuò)展,必須得有函數(shù),沒(méi)有函數(shù)的擴(kuò)展啥用沒(méi)有,如果您覺(jué)得定義函數(shù)很難的話,您又錯(cuò)了,zendAPI就是為了讓您生活變得美好而生的,而不會(huì)讓事情...
摘要:圖示代碼示例服務(wù)實(shí)例索引服務(wù)定義索引是否全局服務(wù)共享單例模式實(shí)例化省略服務(wù)實(shí)例化實(shí)現(xiàn)無(wú)法定位服務(wù)服務(wù)添加失敗感謝文中圖片來(lái)源來(lái)源網(wǎng)絡(luò) 什么是服務(wù)定位器 服務(wù)定位器(service locator)他知道如何定位(創(chuàng)建或者獲取)一個(gè)應(yīng)用所需要的服務(wù),服務(wù)使用者在實(shí)際使用中無(wú)需關(guān)心服務(wù)的實(shí)際實(shí)現(xiàn)。 有什么作用 實(shí)現(xiàn)服務(wù)使用者和服務(wù)的解耦,無(wú)需改變代碼而只是通過(guò)簡(jiǎn)單配置更服服務(wù)實(shí)現(xiàn)。 UML...
前言 在若干次前的一場(chǎng)面試,面試官看我做過(guò)python爬蟲(chóng)/后端 的工作,順帶問(wèn)了我些后端相關(guān)的問(wèn)題:你覺(jué)得什么是后端? 送命題。當(dāng)時(shí)腦瓦特了,答曰:邏輯處理和數(shù)據(jù)增刪改查。。。 showImg(https://user-gold-cdn.xitu.io/2019/4/24/16a4ed4fc8c18078); 當(dāng)場(chǎng)被懟得體無(wú)完膚,羞愧難當(dāng)。事后再反思這問(wèn)題,結(jié)合資料總結(jié)了一下。發(fā)現(xiàn)自己學(xué)過(guò)的Re...
閱讀 2733·2023-04-25 14:15
閱讀 2686·2021-11-04 16:11
閱讀 3385·2021-10-14 09:42
閱讀 434·2019-08-30 15:52
閱讀 2820·2019-08-30 14:03
閱讀 3536·2019-08-30 13:00
閱讀 2105·2019-08-26 11:40
閱讀 3301·2019-08-26 10:25