摘要:設(shè)計(jì)模式設(shè)計(jì)模式基本原則設(shè)計(jì)原則按接口而不是按實(shí)現(xiàn)來編程按接口而不是按實(shí)現(xiàn)編程是指,要將變量設(shè)置為一個(gè)抽象類或接口數(shù)據(jù)類型的實(shí)例,而不是一個(gè)具體實(shí)現(xiàn)的實(shí)例。例如父類的一個(gè)改變會(huì)逐級(jí)向下傳遞給子類實(shí)現(xiàn),這可能會(huì)影響子類使用的某個(gè)算法。
設(shè)計(jì)模式 設(shè)計(jì)模式基本原則
設(shè)計(jì)原則 ① : 按接口而不是按實(shí)現(xiàn)來編程
按接口而不是按實(shí)現(xiàn)編程是指,要將變量設(shè)置為一個(gè)抽象類或接口數(shù)據(jù)類型的實(shí)例,
而不是一個(gè)具體實(shí)現(xiàn)的實(shí)例。這樣可以將設(shè)計(jì)與實(shí)現(xiàn)解耦合。
有些語言變量聲明包含數(shù)據(jù)類型,例如在一個(gè)強(qiáng)類型語言中可以有以下聲明:
如果沒有強(qiáng)類型機(jī)制,可以利用代碼提示保證按接口編程,以上一節(jié)寫過的一段代碼為例
//useProduct.php class useProduct{ public function __construct(){ $apple = new FruitStore(); $book = new BookStore(); $this->doInterface($apple); $this->doInterface($book); } function doInterface(IProduct $product){ //這里的IProduct $product就是一種類型提示,方法類型提示為接口IProduct //無論程序變得多復(fù)雜都沒關(guān)系,只要保證接口 //就可以做出任意的修改和增補(bǔ),不會(huì)破壞程序的其它部分 echo $product->apples(); echo $product->books(); } } $worker = new useProduct(); ?>
設(shè)計(jì)原則 ② : 應(yīng)當(dāng)優(yōu)先選擇對(duì)象組合而不是類繼承
有的OOP程序猿認(rèn)為對(duì)象重用就等同于繼承,一個(gè)類可以有大量屬性和方法,擴(kuò)展這個(gè)類就可以重用所有那些對(duì)象元素,而不用重新編寫代碼。可以擴(kuò)展類,再增加必要的新屬性和方法。下面將舉一個(gè)例子說明對(duì)象組合和類繼承之間的區(qū)別。
首先是繼承的代碼
sum = ( $first + $second ); return $this->sum; } public function simpleDivide($divided, $divisor){ $this->quotient = ( $dividend / $divisor); return $this->quotient; } } ?>
textOut = (string)$num; return $this->textOut; } public function addFace($face,$msg){ $this->fullFace = "" . $face . " : " .$msg; return $this->fullFace; } } ?>
added = $family->simpleAdd(40,60); $this->divided = $family->simpleDivided($this->added,25); $this->textNum = $family->numToText($this->divided); $this->output = $family->addFace("Your results",$this->textNum); echo $this->output; } } $worker = new ClientInherit(); ?>
下面是組合,Client類使用兩個(gè)不同的類,分別包含兩個(gè)方法,DoMath類等同于繼承例子中的父類,所以首先是DoText類
textOut = (string)$num; return $this->textOut; } public function addFace($face,$msg){ $this->fullFace = "" . $face . " : " .$msg; return $this->fullFace; } } ?>
added = $useMath->simpleAdd(40,60); $this->divided = $useMath->simpleDivide($this->added,25); $this->textNum = $useText->numToText($this->divided); $this->output = $useText->addFace("Your results",$this->textNum); echo $this->output; } } ?>
Client類必須包含多個(gè)類,看起來更勝一籌,不過在較大的程序中,組合可以避免維護(hù)多個(gè)繼承層次上的各個(gè)子類,而且還可以避免可能導(dǎo)致的錯(cuò)誤。例如父類的一個(gè)改變會(huì)逐級(jí)向下傳遞給子類實(shí)現(xiàn),這可能會(huì)影響子類使用的某個(gè)算法。
要避免使用繼承形成一長串子類、孫子類、曾孫子類,設(shè)計(jì)模式方法建議使用淺繼承。
設(shè)計(jì)模式是按照作用和范圍來組織的
設(shè)計(jì)模式按作用可以分為以下3類
創(chuàng)建型
顧名思義,就是用來創(chuàng)建對(duì)象的模式,更確切地講,這些模式是對(duì)實(shí)例化過程的抽象,
如果程序越來越以來組合,就會(huì)減少對(duì)硬編碼實(shí)例化的依賴,而更多地以來于一組靈
活的行為,這些行為可以組織到一個(gè)更為復(fù)雜的集合中,創(chuàng)建型模式提供了一些方法
來封裝系統(tǒng)使用的具體類的有關(guān)知識(shí),還可以隱藏實(shí)例創(chuàng)建和組合的相關(guān)信息
結(jié)構(gòu)型
這些模式所關(guān)心的是組合結(jié)構(gòu)應(yīng)當(dāng)保證結(jié)構(gòu)化。結(jié)構(gòu)型類模式采用繼承來組合接口或?qū)崿F(xiàn)。結(jié)構(gòu)型對(duì)象模式則描述了組合對(duì)象來建立新功能的方法。了解結(jié)構(gòu)型模式對(duì)于理解和使用相互關(guān)聯(lián)的類(作為設(shè)計(jì)模式中的參與者)很有幫助
行為型
到目前為止,絕大多數(shù)模式都是行為型對(duì)象,這些模式的核心是算法和對(duì)象之間職責(zé)的分配。這些設(shè)計(jì)模式描述的不只是對(duì)象或類的模式,它們還描述了類和對(duì)象之間的通信模式
設(shè)計(jì)模式按范圍可以分為以下2類
類
在兩類范圍中,第一類范圍是類。這些類模式的重點(diǎn)在于類及其子類之間的關(guān)系,類模式中的關(guān)系是通過繼承建成
對(duì)象
盡管大多數(shù)設(shè)計(jì)模式都屬于對(duì)象范圍,不過與類范圍中的那些模式一樣,很多模式也會(huì)使用繼承。對(duì)象設(shè)計(jì)模式與類模式的區(qū)別在于,對(duì)象模式強(qiáng)調(diào)的是可以在運(yùn)行時(shí)改變的對(duì)象,因此這些模式更具動(dòng)態(tài)性。
設(shè)計(jì)模式作用、范圍和變化
設(shè)計(jì)模式與框架有什么不同與框架相比,設(shè)計(jì)模式是體系結(jié)構(gòu)中更小的元素,也更為抽象,另外設(shè)計(jì)模式?jīng)]有框架那么 特定。因此,設(shè)計(jì)模式更可重用,也比框架靈活。 框架的有點(diǎn)與模板有些類似:它們更有指示性,可以更清楚地指示所解決問題的結(jié)構(gòu)。為了 提供這種易用性,它們不得不放棄了體系結(jié)構(gòu)的靈活性。如果使用框架,構(gòu)建應(yīng)用會(huì)快得多, 但是所構(gòu)建的應(yīng)用會(huì)受到框架本身的約束。框架可以包含面向?qū)ο蠼Y(jié)構(gòu),通常框架是分層的, 每一層處理更大設(shè)計(jì)中的一個(gè)方面。框架的一些特性在設(shè)計(jì)模式中也有體現(xiàn),不過,設(shè)計(jì)模 式?jīng)]有框架那么特定和具體,也沒有那么龐大UML
概念:UML(the Unified Modeling Language——統(tǒng)一建模語言),引入了一個(gè)強(qiáng)大的 圖形化的語法來描述面向?qū)ο笙到y(tǒng)類圖 1.描述類
類是類圖的主要部分,類用帶有類名的方框來描述。
上圖中,圖1最先顯示的是類的名稱,下面兩部分是可選的,用于顯示類名之外的信息。 可以發(fā)現(xiàn)圖1已經(jīng)足夠描述一些類,并非總要在類圖中顯示每個(gè)屬性和方法,甚至不需要 顯示每個(gè)類 通常用斜體的類名(圖2),或者增加{abstract}到類名下(圖3)來表示該類是抽象 類。 第一種方法比第一種方法常用,但是當(dāng)你做筆記時(shí)第二種方法更有用 接口定義的方式和類相同,但接口必須使用一個(gè)衍型(UML的一個(gè)擴(kuò)展),如樓下所示2.屬性
一般來說,屬性用于描述一個(gè)類的屬性,屬性直接列在類名下面的格子中,如樓下所示
屬性前面的符號(hào)表示該屬性可見性的級(jí)別或者是訪問控制
冒號(hào)用于分隔屬性名和它的類型及默認(rèn)值(默認(rèn)值為可選項(xiàng),可以不提供)
Again:只要提供必要的信息,不需要所有細(xì)節(jié)
操作用于描述類方法,操作和屬性使用了相似的語法
(1)可見性符號(hào)放在方法名之前 (2)參數(shù)列表包含在括號(hào)之中 (3)方法如果有返回類型的話,用冒號(hào)來描述 (4)參數(shù)用逗號(hào)來分隔,并且遵守屬性語法 (5)參數(shù)名和它的數(shù)據(jù)類型間用冒號(hào)分隔
如下圖所示
4.描述繼承和實(shí)現(xiàn)繼承關(guān)系用從子類到父類的一條線來表示,線的頂端有一個(gè)空心閉合箭頭
UML用"實(shí)現(xiàn)"來描述接口和實(shí)現(xiàn)接口的類之間的關(guān)系,如果ShopProduct類實(shí)現(xiàn)了Chargeable接口,就可以加入類圖中,如圖所示
一個(gè)類的屬性保存了對(duì)另一個(gè)類的一個(gè)實(shí)例或多個(gè)實(shí)例的引用時(shí),就產(chǎn)生了關(guān)聯(lián)
下圖中為輛各類建立模型,并創(chuàng)建類之間的關(guān)聯(lián),圖中指出Teacher對(duì)象擁有一個(gè)或多個(gè)對(duì)Pupil對(duì)象的引用,或者Pupil對(duì)象擁有一個(gè)或多個(gè)對(duì)Teacher對(duì)象的引用
我們可以用剪頭來描述關(guān)聯(lián)的方向,如果Teacher類擁有Pupil類的一個(gè)實(shí)例,但是Pupil類并沒有Teacher類的實(shí)例,那我們可以讓關(guān)聯(lián)剪頭從Teacher類指向Pupil類,稱為"單向關(guān)聯(lián)"
如果兩個(gè)類剪互相擁有對(duì)方的引用,可以用一個(gè)雙向剪頭來描述這種"雙向關(guān)聯(lián)"關(guān)系
也可以在關(guān)聯(lián)中指定一個(gè)類的實(shí)例被其它類引用的次數(shù),可以通過把次數(shù)或者范圍放在每個(gè)類旁邊來說明。用星號(hào)(*)表示任意次數(shù),如下圖所示,Teacher對(duì)象擁有零個(gè)或多個(gè)Pupil對(duì)象
都描述了一個(gè)類長期持有其它類的一個(gè)或多個(gè)實(shí)例的情況,通過聚合和組合,被 引用的對(duì)象實(shí)例成為引用對(duì)象的一部分。 聚合關(guān)系用一條以空心菱形開頭的線來說明,如下圖所示,定義了兩個(gè)類, SchoolClass和Pupil, SchoolClass類聚合了Pupil (意思就是學(xué)生組成了班級(jí),如果我們要?jiǎng)h除一個(gè)學(xué)校類,不需要同時(shí)刪除)
組合是一個(gè)更強(qiáng)的關(guān)系,在組合中,被包含對(duì)象只能被它的容器所引用,當(dāng)容器刪除 時(shí),她應(yīng)該也被刪除,組合關(guān)系用類似聚合關(guān)系的方式描述,但它的菱形是實(shí)心的 下圖中,Person類持有對(duì)SocialSecurityData對(duì)象的引用,而SocialSecurityData 對(duì)象實(shí)例屬于包含它的Person對(duì)象7.描述使用
使用:即依賴關(guān)系,并非類之間的長久關(guān)系 下圖中,Report類使用了ShopProductWriter對(duì)象,這種使用關(guān)系由一條連接兩個(gè)類 的虛線和開放剪頭表示。Report類沒有把ShopProductWriter保存為類中的屬性, ShopProductWriter對(duì)象則將一組ShopProduct對(duì)象作為屬性8.使用注解
注解:解釋類處理任務(wù)的過程(類圖只能捕捉系統(tǒng)結(jié)構(gòu)) 如下圖,Report對(duì)象使用了ShopProductWriter,但是不知道具體如何實(shí)現(xiàn), 我們使用了注解來補(bǔ)充說明
如圖所示,注解由一個(gè)這叫的方框組成,通常包含偽代碼片段時(shí)序圖
時(shí)序圖是基于對(duì)象而不是基于類的,用于為系統(tǒng)中過程化的行為建模。 如下,為Report對(duì)象輸出產(chǎn)品數(shù)據(jù)的過程建模,從左到右展現(xiàn)了系統(tǒng)的參與者 我們值使用類名來標(biāo)記對(duì)象,如果圖中有同一個(gè)類的多個(gè)對(duì)象實(shí)例在獨(dú)立工作, 可以使用label:class(例如product1 : ShopProduct)格式來包含對(duì)象名
下圖我們從上到下展示了該過程每個(gè)對(duì)象的生命周期
垂直的虛線是生命線,展示了系統(tǒng)中對(duì)象的生命周期,生命線上的矩形說明了過程中的 焦點(diǎn),即某個(gè)對(duì)象的激活期。 顯示對(duì)象間傳遞的消息,這個(gè)圖才更容易被看懂,如下
箭頭表示消息從一個(gè)對(duì)象傳遞到另一個(gè)對(duì)象,返回值一般不寫。 每個(gè)消息都用相關(guān)的方法調(diào)用來標(biāo)記,例如方括號(hào)說明一個(gè)條件,像 {okToPrint} write() 只有在一定條件下write才會(huì)被執(zhí)行 星號(hào)用于表示一個(gè)重復(fù)的操作,可以在方括號(hào)中進(jìn)一步說明 *{for each ShopProduct} write() 該圖含義:Report對(duì)象獲得一個(gè)來自ProductStore對(duì)象的ShopProduct對(duì)象列表。 Report對(duì)象傳遞這個(gè)ShopProduct列表給一個(gè)ShopProcuctWriter對(duì)象,而 ShopProductWriter存放了對(duì)ShopProduct對(duì)象的引用(雖然我們只能從圖中推斷 出折點(diǎn))ShopProductWriter對(duì)象為它引用的每個(gè)ShopProduct對(duì)象調(diào)用ShopProduct:: getSummaryLine(),并添加執(zhí)行結(jié)果到最終的輸出結(jié)果中
本文筆記參考書籍:
《深入PHP:面向?qū)ο蟆⒛J脚c實(shí)踐》第4章
《Learning-PHP設(shè)計(jì)模式》第4章
下節(jié):Chap3:創(chuàng)建型設(shè)計(jì)模式————工廠方法設(shè)計(jì)模式
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/21227.html
摘要:你好,是我琉憶,程序員面試筆試系列圖書的作者。建造者模式介紹建造者模式又名生成器模式,是一種對(duì)象構(gòu)建模式。表示被構(gòu)造的復(fù)雜對(duì)象。創(chuàng)建該產(chǎn)品的內(nèi)部表示并定義它的裝配過程。 你好,是我琉憶,PHP程序員面試筆試系列圖書的作者。 本周(2019.3.11至3.15)的一三五更新的文章如下: 周一:PHP面試常考之設(shè)計(jì)模式——工廠模式周三:PHP面試常考之設(shè)計(jì)模式——建造者模式周五:PHP面...
摘要:面向?qū)ο笤O(shè)計(jì)模式通常以類別或?qū)ο髞砻枋銎渲械年P(guān)系和相互作用,但不涉及用來完成應(yīng)用程序的特定類別或?qū)ο蟆@锸洗鷵Q原則里氏代換原則是面向?qū)ο笤O(shè)計(jì)的基本原則之一。 通俗易懂的設(shè)計(jì)模式 零、使用 1、安裝 2、測(cè)試 一、什么是設(shè)計(jì)模式 二、設(shè)計(jì)模式的類型 三、設(shè)計(jì)模式的六大原則 四、UML類圖 1、看懂UML類圖 2、解釋 五、資料 前言:花了一些時(shí)間再次熟悉了一遍...
摘要:而哈士奇區(qū)別于普通狗,又有新的特征逗比,愛搗亂為了保證類之間的松綁定,通常會(huì)繼承抽象類,而且是淺繼承只有一層子類。如果知道所有類都會(huì)共享一個(gè)公共的行為實(shí)現(xiàn),就使用抽象類,并在其中實(shí)現(xiàn)該行為。 為什么使用OOP OOP是一個(gè)模塊化的過程,目的是為了把復(fù)雜問題簡單化,一個(gè)模塊解決一個(gè)復(fù)雜問題的某一個(gè)方面,即一個(gè)類應(yīng)當(dāng)只有一個(gè)職責(zé) OOP區(qū)別于順序式編程與過程式編程,在于: 1.順序編程...
摘要:它是一款全自動(dòng)圖生成器,支持。但是圖并不方便操作。因?yàn)榻?jīng)常使用來做圖,所以如果能生成一個(gè)可以導(dǎo)入到的文件那就更好了。文件支持導(dǎo)入文件,那文件到底是什么樣子的是導(dǎo)出時(shí),生成的圖片,包含各個(gè)元素。導(dǎo)入主要看的是。 項(xiàng)目需要畫uml圖,手寫浪費(fèi)時(shí)間,于是就搜了一些相關(guān)的工具來生成它。有php插件phpumd等等。發(fā)現(xiàn)了一個(gè)簡單易用的工具,那就是phuml。 Phuml 它是一款全自動(dòng)uml圖...
摘要:負(fù)責(zé)從拉取數(shù)據(jù)源,把數(shù)據(jù)源分詞,建立索引搜索模塊工作流程如下模塊從中拉取數(shù)據(jù)模塊用經(jīng)過中文分詞后的數(shù)據(jù)建立索引客戶端向模塊發(fā)起搜索請(qǐng)求模塊查找索引中的數(shù)據(jù)模塊得到索引中符合要求的數(shù)據(jù)的等數(shù)據(jù)把數(shù)據(jù)返回給客戶端 (整理自《App后臺(tái)開發(fā)運(yùn)維和架構(gòu)實(shí)踐》 作者:曾健生) 一、從業(yè)務(wù)邏輯中提煉API接口 此過程可分為六個(gè)階段: 業(yè)務(wù)邏輯思維導(dǎo)圖 功能——業(yè)務(wù)邏輯思維導(dǎo)圖 基本功能模塊關(guān)系 ...
閱讀 2237·2021-11-22 15:29
閱讀 4116·2021-11-04 16:13
閱讀 1001·2019-08-29 16:58
閱讀 347·2019-08-29 16:08
閱讀 1469·2019-08-23 17:56
閱讀 2394·2019-08-23 17:06
閱讀 3173·2019-08-23 16:55
閱讀 2070·2019-08-23 16:22