摘要:抽象工廠目的創建一系列相關或依賴的對象,而不指定它們的具體類。這個模式是一個真正的設計模式,因為它遵循了依賴反轉原則眾所周知這個代表了真正的面向對象程序設計。
【搬運于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 可以是一個抽象類(也就是說可以有一定的具體實現,就像眾所周知的適配器模式)。
如果對象有復雜的繼承樹,理論上創建對象的生成器也同樣具有復雜的繼承樹。
提示:生成器通常具有流暢的接口,推薦閱讀關于 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的優點是您可以子類化它來實現創建對象的不同方法。
對于簡單的情況,這個抽象類可能只是一個接口。
這個模式是一個 "真正" 的設計模式,因為它遵循了依賴反轉原則 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)結構型設計模式
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/29983.html
摘要:此模式的主要特點是,與不同,其數據模式遵循單一職責原則。圖代碼你可以在上找到這些代碼代理模式目的為昂貴或者無法復制的資源提供接口。圖代碼你可以在上找到這些代碼相關文章設計模式范例創建型設計模式 【搬運于GitHub開源項目DesignPatternsPHP】 項目地址:戳我 2、結構型設計模式 在軟件工程中,結構型設計模式集是用來抽象真實程序中的對象實體之間的關系,并使這種關系可被描...
摘要:第一步打開項目下的文件,在文件中輸入我們的函數的原型聲明代碼。這行代碼注冊一個原型為的函數,當這個函數被執行的時候,我們的函數將被運行時調用。原文地址開發擴展之原生函數定義 在上一篇中我們在hellozapi擴展中我們定義了幾個常量,但是一個有用的擴展,必須得有函數,沒有函數的擴展啥用沒有,如果您覺得定義函數很難的話,您又錯了,zendAPI就是為了讓您生活變得美好而生的,而不會讓事情...
摘要:圖示代碼示例服務實例索引服務定義索引是否全局服務共享單例模式實例化省略服務實例化實現無法定位服務服務添加失敗感謝文中圖片來源來源網絡 什么是服務定位器 服務定位器(service locator)他知道如何定位(創建或者獲取)一個應用所需要的服務,服務使用者在實際使用中無需關心服務的實際實現。 有什么作用 實現服務使用者和服務的解耦,無需改變代碼而只是通過簡單配置更服服務實現。 UML...
前言 在若干次前的一場面試,面試官看我做過python爬蟲/后端 的工作,順帶問了我些后端相關的問題:你覺得什么是后端? 送命題。當時腦瓦特了,答曰:邏輯處理和數據增刪改查。。。 showImg(https://user-gold-cdn.xitu.io/2019/4/24/16a4ed4fc8c18078); 當場被懟得體無完膚,羞愧難當。事后再反思這問題,結合資料總結了一下。發現自己學過的Re...
閱讀 2758·2023-04-25 14:15
閱讀 2704·2021-11-04 16:11
閱讀 3395·2021-10-14 09:42
閱讀 443·2019-08-30 15:52
閱讀 2826·2019-08-30 14:03
閱讀 3546·2019-08-30 13:00
閱讀 2113·2019-08-26 11:40
閱讀 3308·2019-08-26 10:25