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