摘要:事實(shí)上,設(shè)計(jì)模式的解釋如下另一方面,設(shè)計(jì)模式提供了一種廣泛的可重用的方式來解決我們?nèi)粘>幊讨谐3S鲆姷膯栴}。原型模式有些時(shí)候,部分對象需要被初始化多次。
本文為翻譯文章
原文地址:Design Patterns in PHP
如果打算學(xué)習(xí)PHP的童鞋可以參考下筆者的編程語言學(xué)習(xí)知識體系要點(diǎn)列表
本文主要討論下Web開發(fā)中,準(zhǔn)確而言,是PHP開發(fā)中的相關(guān)的設(shè)計(jì)模式及其應(yīng)用。有經(jīng)驗(yàn)的開發(fā)者肯定對于設(shè)計(jì)模式非常熟悉,但是本文主要是針對那些初級的開發(fā)者。首先我們要搞清楚到底什么是設(shè)計(jì)模式,設(shè)計(jì)模式并不是一種用來解釋的模式,它們并不是像鏈表那樣的常見的數(shù)據(jù)結(jié)構(gòu),也不是某種特殊的應(yīng)用或者框架設(shè)計(jì)。事實(shí)上,設(shè)計(jì)模式的解釋如下:
descriptions of communicating objects and classes that are customized to solve a general design problem in a particular context.
另一方面,設(shè)計(jì)模式提供了一種廣泛的可重用的方式來解決我們?nèi)粘>幊讨谐3S鲆姷膯栴}。設(shè)計(jì)模式并不一定就是一個(gè)類庫或者第三方框架,它們更多的表現(xiàn)為一種思想并且廣泛地應(yīng)用在系統(tǒng)中。它們也表現(xiàn)為一種模式或者模板,可以在多個(gè)不同的場景下用于解決問題。設(shè)計(jì)模式可以用于加速開發(fā),并且將很多大的想法或者設(shè)計(jì)以一種簡單地方式實(shí)現(xiàn)。當(dāng)然,雖然設(shè)計(jì)模式在開發(fā)中很有作用,但是千萬要避免在不適當(dāng)?shù)膱鼍罢`用它們。
目前常見的設(shè)計(jì)模式主要有23種,根據(jù)使用目標(biāo)的不同可以分為以下三大類:
創(chuàng)建模式:用于創(chuàng)建對象從而將某個(gè)對象從實(shí)現(xiàn)中解耦合。
架構(gòu)模式:用于在不同的對象之間構(gòu)造大的對象結(jié)構(gòu)。
行為模式:用于在不同的對象之間管理算法、關(guān)系以及職責(zé)。
Creational Patterns Singleton(單例模式)單例模式是最常見的模式之一,在Web應(yīng)用的開發(fā)中,常常用于允許在運(yùn)行時(shí)為某個(gè)特定的類創(chuàng)建一個(gè)可訪問的實(shí)例。
mix = "test"; $secondProduct->mix = "example"; print_r($firstProduct->mix); // example print_r($secondProduct->mix); // example
在很多情況下,需要為系統(tǒng)中的多個(gè)類創(chuàng)建單例的構(gòu)造方式,這樣,可以建立一個(gè)通用的抽象父工廠方法:
a[] = 1; SecondProduct::getInstance()->a[] = 2; FirstProduct::getInstance()->a[] = 3; SecondProduct::getInstance()->a[] = 4; print_r(FirstProduct::getInstance()->a); // array(1, 3) print_r(SecondProduct::getInstance()->a); // array(2, 4)Registry
注冊臺模式并不是很常見,它也不是一個(gè)典型的創(chuàng)建模式,只是為了利用靜態(tài)方法更方便的存取數(shù)據(jù)。
Factory(工廠模式)工廠模式是另一種非常常用的模式,正如其名字所示:確實(shí)是對象實(shí)例的生產(chǎn)工廠。某些意義上,工廠模式提供了通用的方法有助于我們?nèi)カ@取對象,而不需要關(guān)心其具體的內(nèi)在的實(shí)現(xiàn)。
getProduct(); $factory = new SecondFactory(); $secondProduct = $factory->getProduct(); print_r($firstProduct->getName()); // The first product print_r($secondProduct->getName()); // Second productAbstractFactory(抽象工廠模式)有些情況下我們需要根據(jù)不同的選擇邏輯提供不同的構(gòu)造工廠,而對于多個(gè)工廠而言需要一個(gè)統(tǒng)一的抽象工廠:
getProduct(); Config::$factory = 2; $secondProduct = AbstractFactory::getFactory()->getProduct(); print_r($firstProduct->getName()); // The first product from the first factory print_r($secondProduct->getName()); // Second product from second factoryObject pool(對象池)對象池可以用于構(gòu)造并且存放一系列的對象并在需要時(shí)獲取調(diào)用:
id = $id; } public function getId() { return $this->id; } } class Factory { protected static $products = array(); public static function pushProduct(Product $product) { self::$products[$product->getId()] = $product; } public static function getProduct($id) { return isset(self::$products[$id]) ? self::$products[$id] : null; } public static function removeProduct($id) { if (array_key_exists($id, self::$products)) { unset(self::$products[$id]); } } } Factory::pushProduct(new Product("first")); Factory::pushProduct(new Product("second")); print_r(Factory::getProduct("first")->getId()); // first print_r(Factory::getProduct("second")->getId()); // secondLazy Initialization(延遲初始化)對于某個(gè)變量的延遲初始化也是常常被用到的,對于一個(gè)類而言往往并不知道它的哪個(gè)功能會被用到,而部分功能往往是僅僅被需要使用一次。
firstProduct) { $this->firstProduct = new FirstProduct(); } return $this->firstProduct; } public function getSecondProduct() { if (!$this->secondProduct) { $this->secondProduct = new SecondProduct(); } return $this->secondProduct; } } class FirstProduct implements Product { public function getName() { return "The first product"; } } class SecondProduct implements Product { public function getName() { return "Second product"; } } $factory = new Factory(); print_r($factory->getFirstProduct()->getName()); // The first product print_r($factory->getSecondProduct()->getName()); // Second product print_r($factory->getFirstProduct()->getName()); // The first productPrototype(原型模式)有些時(shí)候,部分對象需要被初始化多次。而特別是在如果初始化需要耗費(fèi)大量時(shí)間與資源的時(shí)候進(jìn)行預(yù)初始化并且存儲下這些對象。
product = $product; } public function getProduct() { return clone $this->product; } } class SomeProduct implements Product { public $name; } $prototypeFactory = new Factory(new SomeProduct()); $firstProduct = $prototypeFactory->getProduct(); $firstProduct->name = "The first product"; $secondProduct = $prototypeFactory->getProduct(); $secondProduct->name = "Second product"; print_r($firstProduct->name); // The first product print_r($secondProduct->name); // Second productBuilder(構(gòu)造者)構(gòu)造者模式主要在于創(chuàng)建一些復(fù)雜的對象:
name = $name; } public function getName() { return $this->name; } } abstract class Builder { protected $product; final public function getProduct() { return $this->product; } public function buildProduct() { $this->product = new Product(); } } class FirstBuilder extends Builder { public function buildProduct() { parent::buildProduct(); $this->product->setName("The product of the first builder"); } } class SecondBuilder extends Builder { public function buildProduct() { parent::buildProduct(); $this->product->setName("The product of second builder"); } } class Factory { private $builder; public function __construct(Builder $builder) { $this->builder = $builder; $this->builder->buildProduct(); } public function getProduct() { return $this->builder->getProduct(); } } $firstDirector = new Factory(new FirstBuilder()); $secondDirector = new Factory(new SecondBuilder()); print_r($firstDirector->getProduct()->getName()); // The product of the first builder print_r($secondDirector->getProduct()->getName()); // The product of second builderStructural Patterns Decorator(裝飾器模式)裝飾器模式允許我們根據(jù)運(yùn)行時(shí)不同的情景動態(tài)地為某個(gè)對象調(diào)用前后添加不同的行為動作。
_html = "Adapter(適配器模式)__text__
"; } public function set($html) { $this->_html = $html; } public function render() { echo $this->_html; } } class Template2 extends HtmlTemplate { protected $_element; public function __construct($s) { $this->_element = $s; $this->set("" . $this->_html . "
"); } public function __call($name, $args) { $this->_element->$name($args[0]); } } class Template3 extends HtmlTemplate { protected $_element; public function __construct($s) { $this->_element = $s; $this->set("" . $this->_html . ""); } public function __call($name, $args) { $this->_element->$name($args[0]); } }這種模式允許使用不同的接口重構(gòu)某個(gè)類,可以允許使用不同的調(diào)用方式進(jìn)行調(diào)用:
author = $author_in; $this->title = $title_in; } function getAuthor() { return $this->author; } function getTitle() { return $this->title; } } class BookAdapter { private $book; function __construct(SimpleBook $book_in) { $this->book = $book_in; } function getAuthorAndTitle() { return $this->book->getTitle()." by ".$this->book->getAuthor(); } } // Usage $book = new SimpleBook("Gamma, Helm, Johnson, and Vlissides", "Design Patterns"); $bookAdapter = new BookAdapter($book); echo "Author and Title: ".$bookAdapter->getAuthorAndTitle(); function echo $line_in) { echo $line_in."Behavioral Patterns Strategy(策略模式)
"; }測試模式主要為了讓客戶類能夠更好地使用某些算法而不需要知道其具體的實(shí)現(xiàn)。
Observer(觀察者模式)某個(gè)對象可以被設(shè)置為是可觀察的,只要通過某種方式允許其他對象注冊為觀察者。每當(dāng)被觀察的對象改變時(shí),會發(fā)送信息給觀察者。
_observers as $obs) $obs->onChanged($this, $name); } public function addObserver($observer) { $this->_observers []= $observer; } } class CustomerListLogger implements Observer { public function onChanged($sender, $args) { echo( ""$args" Customer has been added to the list " ); } } $ul = new UserList(); $ul->addObserver( new CustomerListLogger() ); $ul->addCustomer( "Jack" );Chain of responsibility(責(zé)任鏈模式)這種模式有另一種稱呼:控制鏈模式。它主要由一系列對于某些命令的處理器構(gòu)成,每個(gè)查詢會在處理器構(gòu)成的責(zé)任鏈中傳遞,在每個(gè)交匯點(diǎn)由處理器判斷是否需要對它們進(jìn)行響應(yīng)與處理。每次的處理程序會在有處理器處理這些請求時(shí)暫停。
_commands[]= $cmd; } public function runCommand($name, $args) { foreach($this->_commands as $cmd) { if ($cmd->onCommand($name, $args)) return; } } } class CustCommand implements Command { public function onCommand($name, $args) { if ($name != "addCustomer") return false; echo("This is CustomerCommand handling "addCustomer" "); return true; } } class MailCommand implements Command { public function onCommand($name, $args) { if ($name != "mail") return false; echo("This is MailCommand handling "mail" "); return true; } } $cc = new CommandChain(); $cc->addCommand( new CustCommand()); $cc->addCommand( new MailCommand()); $cc->runCommand("addCustomer", null); $cc->runCommand("mail", null);
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/21149.html
摘要:簡單字符串緩存實(shí)戰(zhàn)完整實(shí)戰(zhàn)種設(shè)計(jì)模式設(shè)計(jì)模式是面向?qū)ο蟮淖罴褜?shí)踐成為專業(yè)程序員路上用到的各種優(yōu)秀資料神器及框架成為一名專業(yè)程序員的道路上,需要堅(jiān)持練習(xí)學(xué)習(xí)與積累,技術(shù)方面既要有一定的廣度,更要有自己的深度。 微型新聞系統(tǒng)的開發(fā)(PHP 5.4 + MySQL 5.5) 微型新聞系統(tǒng)的開發(fā)(PHP 5.4 + MySQL 5.5) 九個(gè)很有用的 PHP 代碼 php 代碼 國內(nèi)值得關(guān)注的...
摘要:我們今天也來做一個(gè)萬能遙控器設(shè)計(jì)模式適配器模式將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。今天要介紹的仍然是創(chuàng)建型設(shè)計(jì)模式的一種建造者模式。設(shè)計(jì)模式的理論知識固然重要,但 計(jì)算機(jī)程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計(jì)模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對容器接口對象進(jìn)行操作,第二類是返回一個(gè)容器接口對象,上節(jié)我們介紹了...
摘要:我們今天也來做一個(gè)萬能遙控器設(shè)計(jì)模式適配器模式將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。今天要介紹的仍然是創(chuàng)建型設(shè)計(jì)模式的一種建造者模式。設(shè)計(jì)模式的理論知識固然重要,但 計(jì)算機(jī)程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計(jì)模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對容器接口對象進(jìn)行操作,第二類是返回一個(gè)容器接口對象,上節(jié)我們介紹了...
摘要:分別為適配器模式,裝飾器模式,代理模式,外觀模式,橋接模式,組合模式,享元模式。設(shè)計(jì)模式五適配器模式適配器模式將某個(gè)對象的接生成器和協(xié)程的實(shí)現(xiàn)在這篇文章中,作者針對那些比較難以理解的概念,以一個(gè)更為通俗的方式去講明白。。 PHP 源碼注解 PHP 的詳細(xì)源碼注解 PHP 字符串操作整理 一些有關(guān)字符串的常用操作。 Redis 常見七種使用場景 (PHP 實(shí)戰(zhàn)) 這篇文章主要介紹利用 R...
閱讀 2774·2021-11-17 09:33
閱讀 3109·2021-10-25 09:44
閱讀 1216·2021-10-11 10:59
閱讀 2410·2021-09-27 13:34
閱讀 2918·2021-09-07 10:19
閱讀 2146·2019-08-29 18:46
閱讀 1541·2019-08-29 12:55
閱讀 935·2019-08-23 17:11