国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
設(shè)計(jì)模式隨筆系列:鴨子-策略模式(Strategy)[原] - Justin's Tec...

設(shè)計(jì)模式隨筆系列:鴨子-策略模式(Strategy)[原]

鴨子-策略模式(Strategy

前言

萬事開頭難,最近對(duì)這句話體會(huì)深刻!這篇文章是這個(gè)系列正式開始介紹設(shè)計(jì)模式的第一篇,所以肩負(fù)著確定這個(gè)系列風(fēng)格的歷史重任,它在我腦袋里默默地醞釀了好多天,卻只搜刮出了一點(diǎn)兒不太清晰的輪廓,可是時(shí)間不等人,以后再多“迭代”幾次吧!在前面的隨筆里,我已經(jīng)提到了,這個(gè)系列準(zhǔn)備以《Head First Design Patterns》的結(jié)構(gòu)為主線,所以每個(gè)模式的核心故事都是取材于此書,在此再次聲明一下。不管怎樣,宗旨是為了跟大家一起循序漸進(jìn)地去認(rèn)識(shí)設(shè)計(jì)模式。

上一篇:模式和原則,得到很多朋友的支持和鼓勵(lì),這里再次深表感謝。這里我還是想呼吁一下,希望大家看過后多提寶貴意見,反對(duì)意見更好,關(guān)鍵是我們?cè)诨?dòng)中可以共同進(jìn)步,因?yàn)榻?jīng)驗(yàn)告訴我討論(爭(zhēng)論更甚)出來的火花,總是印象最深刻的。

其實(shí)策略模式是一個(gè)很簡(jiǎn)單的模式,也是一個(gè)很常用的模式,可謂短小精悍。我在介紹這個(gè)模式的同時(shí),為了加深大家對(duì)OO的理解,還會(huì)反復(fù)強(qiáng)調(diào)前面講過的設(shè)計(jì)原則和GRASP模式。這個(gè)系列的文章前后多少會(huì)有一些關(guān)聯(lián)的連續(xù)性,但是單獨(dú)一篇文章針對(duì)單一模式也一定是獨(dú)立的,所以不論大家想從前往后連續(xù)看也好,還是挑喜歡的跳著看,都沒有問題。

“羅嗦了這么多,太唐僧了吧,快點(diǎn)開始吧(爛西紅柿和臭雞蛋從四面八方飛來)

模擬鴨子

Joe是一名OO程序員,他為一家開發(fā)模擬鴨子池塘游戲的公司工作,該公司的主要產(chǎn)品是一種可以模擬展示多種會(huì)游泳和呷呷叫的鴨子的游戲。這個(gè)游戲是使用標(biāo)準(zhǔn)的面向?qū)ο蠹夹g(shù)開發(fā)的,系統(tǒng)里所有鴨子都繼承于Duck基類,系統(tǒng)的核心類圖如下:

如圖所示,在Duck基類里實(shí)現(xiàn)了公共的quack()swim()方法,而MallardDuckRedheadDuck可以分別覆蓋實(shí)現(xiàn)自己的display()方法,這樣即重用了公共的部分,又支持不同子類的個(gè)性化擴(kuò)展。從目前的情況看,這是一個(gè)很好的設(shè)計(jì),哈!  

 

但是,商場(chǎng)如戰(zhàn)場(chǎng),不進(jìn)則退。Joe的公司最近的日子不好過,盜版泛濫,再加上競(jìng)爭(zhēng)對(duì)手的圍追堵劫,已經(jīng)拖欠好幾個(gè)月工資了。因此,公司高層在一次集體“腐敗”后,決定一定要給系統(tǒng)增加一些超玄的功能,以徹底擊垮競(jìng)爭(zhēng)對(duì)手。經(jīng)過董事會(huì)討論,最終覺得如果能讓鴨子飛起來,那么一定可以給對(duì)手致命一擊。于是Joe的上司對(duì)董事們拍著胸脯說:“這沒有問題,Joe是一個(gè)OO程序員,這對(duì)他來說太簡(jiǎn)單了!我們保證一周內(nèi)結(jié)束戰(zhàn)斗。”

接到任務(wù)的Joe絲毫不敢怠慢,研究了上級(jí)的指示以后,發(fā)現(xiàn)只要在Duck里增加一個(gè)fly()方法就可以搞定了,這樣所有繼承Duck的鴨子就都擁有了會(huì)飛的能力,哈!這回獎(jiǎng)金有盼頭啦!改進(jìn)后的系統(tǒng)類圖如下:


    Joe的上司很高興,帶著新產(chǎn)品給董事們演示去了……  

……

Joe的上司:“我正在給董事們演示你會(huì)飛的鴨子,但是怎么有很多橡皮鴨子也在四處亂飛呢?你在耍我嗎?你還想不想混啦?!”(此處省略粗話100)

Joe被嚇壞了,到手的獎(jiǎng)金泡湯了!冷靜下來的Joe發(fā)現(xiàn),原來在Duck類里增加的方法,也同樣被繼承于DuckRubberDuck類繼承了,所以就有了會(huì)飛的橡皮鴨子,這是嚴(yán)重違反該系統(tǒng)“真實(shí)模擬各種鴨子”的原則的!那么該怎么辦呢?Joe很郁悶!他突然想到:如果在RubberDuck類里把fly()方法重寫一下會(huì)如何?在RubberDuck類的fly()里讓橡皮鴨子什么都不做,不就一切OK了嗎!那以后再增加一個(gè)木頭鴨子呢?它不會(huì)飛也不會(huì)叫,那不是要再重寫quack()fly()方法,以后再增加其它特殊的鴨子都要這樣,這不是太麻煩了,而且也很混亂。

最終,Joe認(rèn)識(shí)到使用繼承不是辦法,因?yàn)樗纳纤就ㄖ?,董事?huì)決定以后每6個(gè)月就會(huì)升級(jí)一次系統(tǒng),以應(yīng)對(duì)市場(chǎng)競(jìng)爭(zhēng),所以未來的變化會(huì)很頻繁,而且還不可預(yù)知。如果以后靠逐個(gè)類去判斷是否重寫了quack()fly()方法來應(yīng)對(duì)變化,顯然混不下去!

Joe這時(shí)很迷惑,為什么屢試不爽的繼承,在系統(tǒng)維護(hù)升級(jí)的時(shí)候,無法很好地支持重用呢?)

那么使用接口怎么樣?我可以把fly()方法放在接口里,只有那些會(huì)飛的鴨子才需要實(shí)現(xiàn)這個(gè)接口,最好把quack()方法也拿出來放到一個(gè)接口里,因?yàn)橛行喿邮遣粫?huì)叫的。就像下面這樣:



Joe的上司知道后怒了:“你這樣做難道是希望所有需要quack()fly()方法的鴨子都去重復(fù)實(shí)現(xiàn)這兩個(gè)方法的功能嗎?就這么幾個(gè)鴨子還好說,但是我們有幾十、上百個(gè)鴨子的時(shí)候你怎么辦?如果某個(gè)方法要做一點(diǎn)修改,難道你要重復(fù)修改上百遍嗎?你是不是瘋啦?”

 

呵呵!如果你是Joe,你該怎么辦?

我們知道,并不是所有的鴨子都會(huì)飛、會(huì)叫,所以繼承不是正確的方法。但是雖然上面的使用Flyable接口的方法,可以解決部分問題(不再有會(huì)飛的橡皮鴨子),但是這個(gè)解決方案卻徹底破壞了重用,它帶來了另一個(gè)維護(hù)的噩夢(mèng)!而且還有一個(gè)問題我們前面沒有提到,難道所有的鴨子的飛行方式、叫聲等行為都是一模一樣的嗎?不可能吧!

說到這里,為了能幫助Joe擺脫困境,我們有必要先停下來,重新回顧一些面向?qū)ο笤O(shè)計(jì)原則。請(qǐng)您告訴我:“什么東西是在軟件開發(fā)過程中是恒定不變的?”,您想到了嗎?對(duì),那就是變化本身,正所謂“計(jì)劃沒有變化快”,所以直面“變化這個(gè)事實(shí)”才是正道!Joe面對(duì)的問題是,鴨子的行為在子類里持續(xù)不斷地改變,所以讓所有的子類都擁有基類的行為是不適當(dāng)?shù)模褂蒙厦娴慕涌诘姆绞?,又破壞了代碼重用。現(xiàn)在就需要用到我們的第一個(gè)設(shè)計(jì)原則:

Identify the aspects of your application that vary and separate them from what stays the same.(找到系統(tǒng)中變化的部分,將變化的部分同其它穩(wěn)定的部分隔開。)

換句話說就是:“找到變化并且把它封裝起來,稍后你就可以在不影響其它部分的情況下修改或擴(kuò)展被封裝的變化部分。” 盡管這個(gè)概念很簡(jiǎn)單,但是它幾乎是所有設(shè)計(jì)模式的基礎(chǔ),所有模式都提供了使系統(tǒng)里變化的部分獨(dú)立于其它部分的方法。

OK!現(xiàn)在我們已經(jīng)有了一條設(shè)計(jì)原則,那么Joe的問題怎么辦呢?就鴨子的問題來說,變化的部分就是子類里的行為。所以我們要把這部分行為封裝起來,省得它們老惹麻煩!從目前的情況看,就是fly()quack()行為總是不老實(shí),而swim()行為是很穩(wěn)定的,這個(gè)行為是可以使用繼承來實(shí)現(xiàn)代碼重用的,所以,我們需要做的就是把fly()quack()行為從Duck基類里隔離出來。我們需要?jiǎng)?chuàng)建兩組不同的行為,一組表示fly()行為,一組表示quack()行為。為什么是兩組而不是兩個(gè)呢?因?yàn)閷?duì)于不同的子類來說,fly()quack()的表現(xiàn)形式都是不一樣的,有的鴨子嘎嘎叫,有的卻呷呷叫。有了這兩組行為,我們就可以組合出不同的鴨子,例如:我們可能想要實(shí)例化一個(gè)新的MallardDuck(野鴨)實(shí)例,并且給它初始化一個(gè)特殊類型的飛行行為(野鴨飛行能力比較強(qiáng))。那么,如果我們可以這樣,更進(jìn)一步,為什么我們不可以動(dòng)態(tài)地改變一個(gè)鴨子的行為呢?換句話說,我們將在Duck類里包含行為設(shè)置方法,所以我們可以說在運(yùn)行時(shí)改變MallardDuck的飛行行為,這聽起來更酷更靈活了!那么我們到底要怎么做呢?回答這個(gè)問題,先要看一下我們的第二個(gè)設(shè)計(jì)原則:

Program to an interface, not an implementation.(面向接口編程,而不要面向?qū)崿F(xiàn)編程。)

嘿!對(duì)于這個(gè)原則,不論是耳朵還是眼睛,是不是都太熟悉了!“接口”這個(gè)詞已經(jīng)被賦予太多的含義,搞的大家一說點(diǎn)兒屁事就滿嘴往外蹦“接口”。那么它到底是什么意思呢?我們這里說的接口是一個(gè)抽象的概念,不局限于語言層面的接口(例如C#里的interface)。一個(gè)接口也可以是一個(gè)抽象類,或者一個(gè)基類也可以看作是一種接口的表現(xiàn)形式,因?yàn)榛愖兞靠梢杂脕硪闷渥宇?。要點(diǎn)在于,我們?cè)诿嫦蚪涌诰幊痰臅r(shí)候,可以使用多態(tài),那么實(shí)際運(yùn)行的代碼只依賴于具體的接口(interface,抽象類,基類),而不管這些接口提供的功能是如何實(shí)現(xiàn)的,也就是說,接口將系統(tǒng)的不同部分隔離開來,同時(shí)又將它們連接在一起。我的神啊!接口真是太偉大了!(爛西紅柿和臭雞蛋從四面八方飛來)

OK!這回該徹底解決Joe的問題了!

根據(jù)面向接口編程的設(shè)計(jì)原則,我們應(yīng)該用接口來隔離鴨子問題中變化的部分,也就是鴨子的不穩(wěn)定的行為(fly()、quack())。我們要用一個(gè)FlyBehavior接口表示鴨子的飛行行為,這個(gè)接口可以有多種不同的實(shí)現(xiàn)方式,可以“橫”著分,也可以“豎”著分,管它呢!這樣做的好處就是我們將鴨子的行為實(shí)現(xiàn)在一組獨(dú)立的類里,具體的鴨子是通過FlyBehavior這個(gè)接口來調(diào)用這個(gè)行為的,因?yàn)?/span>Duck只依賴FlyBehavior接口,所以不需要管FlyBehavior是如何被實(shí)現(xiàn)的。如下面的類圖,FlyBehaviorQuackBehavior接口都有不同的實(shí)現(xiàn)方式!

Joe已經(jīng)暈了,“你說了這么多,全是大白話,來點(diǎn)代碼行不行,我要C#的!”。說到這里,我們也該開始徹底改造這個(gè)設(shè)計(jì)了,并會(huì)在最后附加部分代碼來幫助大家理解。  

 

第一步:我們要給Duck類增加兩個(gè)接口類型的實(shí)例變量,分別是flyBehaviorquackBehavior,它們其實(shí)就是新的設(shè)計(jì)里的“飛行”和“叫喚”行為。每個(gè)鴨子對(duì)象都將會(huì)使用各種方式來設(shè)置這些變量,以引用它們期望的運(yùn)行時(shí)的特殊行為類型(使用橫著飛,吱吱叫,等等)。

第二步:我們還要把fly()quack()方法從Duck類里移除,因?yàn)槲覀円呀?jīng)把這些行為移到FlyBehaviorQuackBehavior接口里了。我們將使用兩個(gè)相似的PerformFly()PerformQuack()方法來替換fly()qucak()方法,后面你會(huì)看到這兩個(gè)新方法是如何起作用的。

第三步:我們要考慮什么時(shí)候初始化flyBehaviorquackBehavior變量。最簡(jiǎn)單的辦法就是在Duck類初始化的時(shí)候同時(shí)初始化他們。但是我們這里還有更好的辦法,就是提供兩個(gè)可以動(dòng)態(tài)設(shè)置變量值的方法SetFlyBehavior()SetQuackBehavior(),那么就可以在運(yùn)行時(shí)動(dòng)態(tài)改變鴨子的行為了。

下面是修改后的Duck類圖:

我們?cè)倏纯凑麄€(gè)設(shè)計(jì)修改后的類圖:

 


最后大家再看看演示代碼,因?yàn)榇a比較多,就不貼出來了,大家可以下載后參考:
。下面是演示代碼的執(zhí)行結(jié)果:

 


這就是策略模式

 

前面說了那么多,現(xiàn)在終于到了正式介紹我們今天的主角的時(shí)候啦!此刻心情真是好激動(dòng)??!其實(shí)我們?cè)谇懊婢褪鞘褂?/span>Strategy模式幫Joe度過了難過,真不知道他發(fā)了獎(jiǎng)金后要怎么感謝我們啊。OK!下面先看看官方的定義:

The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.(策略模式定義了一系列的算法,并將每一個(gè)算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨(dú)立于使用它的客戶而獨(dú)立變化。)

怎么樣,有了前面Joe的經(jīng)歷,這個(gè)定義理解起來還不那么太費(fèi)勁吧?我想凡是認(rèn)真看到這里的人,應(yīng)該都能理解的。那么下面再畫蛇添足地羅嗦幾句,給那些還不太理解的朋友一個(gè)機(jī)會(huì)吧。J

Context(應(yīng)用場(chǎng)景):

 

l         需要使用ConcreteStrategy提供的算法。

l         內(nèi)部維護(hù)一個(gè)Strategy的實(shí)例。

l         負(fù)責(zé)動(dòng)態(tài)設(shè)置運(yùn)行時(shí)Strategy具體的實(shí)現(xiàn)算法。

l         負(fù)責(zé)跟Strategy之間的交互和數(shù)據(jù)傳遞。

Strategy(抽象策略類)

l         定義了一個(gè)公共接口,各種不同的算法以不同的方式實(shí)現(xiàn)這個(gè)接口,Context使用這個(gè)接口調(diào)用不同的算法,一般使用接口或抽象類實(shí)現(xiàn)。

ConcreteStrategy(具體策略類)

l         實(shí)現(xiàn)了Strategy定義的接口,提供具體的算法實(shí)現(xiàn)。

 

還不理解?!我的神??!那再看看下面的順序圖吧,這是最后的機(jī)會(huì)啦!


應(yīng)用場(chǎng)景和優(yōu)缺點(diǎn)

上面我們已經(jīng)看過了Strategy模式的詳細(xì)介紹,下面我們?cè)賮砗?jiǎn)單說說這個(gè)模式的優(yōu)缺點(diǎn)吧!怎么說呢,人無完人,設(shè)計(jì)模式也不是萬能的,每一個(gè)模式都有它的使命,也就是說只有在特定的場(chǎng)景下才能發(fā)揮其功效。我們要使用好模式,就必須熟知各個(gè)模式的應(yīng)用場(chǎng)景。

對(duì)于Strategy模式來說,主要有這些應(yīng)用場(chǎng)景:

1、  多個(gè)類只區(qū)別在表現(xiàn)行為不同,可以使用Strategy模式,在運(yùn)行時(shí)動(dòng)態(tài)選擇具體要執(zhí)行的行為。(例如FlyBehaviorQuackBehavior)

2、  需要在不同情況下使用不同的策略(算法),或者策略還可能在未來用其它方式來實(shí)現(xiàn)。(例如FlyBehaviorQuackBehavior的具體實(shí)現(xiàn)可任意變化或擴(kuò)充)

3、  對(duì)客戶(Duck)隱藏具體策略(算法)的實(shí)現(xiàn)細(xì)節(jié),彼此完全獨(dú)立。

 

對(duì)于Strategy模式來說,主要有如下優(yōu)點(diǎn):

1、  提供了一種替代繼承的方法,而且既保持了繼承的優(yōu)點(diǎn)(代碼重用)還比繼承更靈活(算法獨(dú)立,可以任意擴(kuò)展)。

2、  避免程序中使用多重條件轉(zhuǎn)移語句,使系統(tǒng)更靈活,并易于擴(kuò)展。

3、  遵守大部分GRASP原則和常用設(shè)計(jì)原則,高內(nèi)聚、低偶合。

對(duì)于Strategy模式來說,主要有如下缺點(diǎn):

1、  因?yàn)槊總€(gè)具體策略類都會(huì)產(chǎn)生一個(gè)新類,所以會(huì)增加系統(tǒng)需要維護(hù)的類的數(shù)量。

 

    備注:關(guān)于場(chǎng)景和優(yōu)缺點(diǎn),上面肯定說得不夠全面,歡迎大家來補(bǔ)充。

.NET框架里的應(yīng)用

Strategy模式的應(yīng)用非常廣泛,也許大家有意無意之間一直都在使用。這里舉一個(gè).NET框架里使用Strategy模式的例子,象這樣的例子其實(shí)還有很多,只要大家細(xì)心體會(huì)就一定會(huì)發(fā)現(xiàn)的。

如果寫過程序,那么ArrayList類肯定都會(huì)用過吧,那么它的Sort方法想必大家也一定不陌生了。Sort方法的定義如下:

public virtual void Sort (IComparer comparer)

可以看到Sort方法接收一個(gè)IComparer類型的參數(shù),那么這個(gè)IComparer接口是做什么用的呢?下面我們看一段程序,下面的代碼示例演示如何使用默認(rèn)比較器和一個(gè)反轉(zhuǎn)排序順序的自定義比較器,對(duì) ArrayList 中的值進(jìn)行排序。(完全引自MSDNms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.NETDEVFX.v20.chs/cpref2/html/M_System_Collections_ArrayList_Sort_1_a2d90598.htm)

 

 1
using System;
 2
using System.Collections;
 3

 4
public class SamplesArrayList  {
 5
 
 6
   
public class myReverserClass : IComparer  {
 7

 8
      
// Calls CaseInsensitiveComparer.Compare with the parameters reversed.
 9
      int IComparer.Compare( Object x, Object y )  {
10
          
return( (new CaseInsensitiveComparer()).Compare( y, x ) );
11
      }

12

13
   }

14

15
   
public static void Main()  {
16
 
17
      
// Creates and initializes a new ArrayList.
18
      ArrayList myAL = new ArrayList();
19
      myAL.Add( 
"The" );
20
      myAL.Add( 
"quick" );
21
      myAL.Add( 
"brown" );
22
      myAL.Add( 
"fox" );
23
      myAL.Add( 
"jumps" );
24
      myAL.Add( 
"over" );
25
      myAL.Add( 
"the" );
26
      myAL.Add( 
"lazy" );
27
      myAL.Add( 
"dog" );
28
 
29
      
// Displays the values of the ArrayList.
30
      Console.WriteLine( "The ArrayList initially contains the following values:" );
31
      PrintIndexAndValues( myAL );
32
 
33
      
// Sorts the values of the ArrayList using the default comparer.
34
      myAL.Sort();
35
      Console.WriteLine( 
"After sorting with the default comparer:" );
36
      PrintIndexAndValues( myAL );
37

38
      
// Sorts the values of the ArrayList using the reverse case-insensitive comparer.
39
      IComparer myComparer = new myReverserClass();
40
      myAL.Sort( myComparer );
41
      Console.WriteLine( 
"After sorting with the reverse case-insensitive comparer:" );
42
      PrintIndexAndValues( myAL );
43

44
   }

45
 
46
   
public static void PrintIndexAndValues( IEnumerable myList )  {
47
      
int i = 0;
48
      
foreach ( Object obj in myList )
49
         Console.WriteLine( 
"\t[{0}]:\t{1}", i++, obj );
50
      Console.WriteLine();
51
   }

52

53
}

54

55

56
/* 
57
This code produces the following output.
58
The ArrayList initially contains the following values:
59
        [0]:    The
60
        [1]:    quick
61
        [2]:    brown
62
        [3]:    fox
63
        [4]:    jumps
64
        [5]:    over
65
        [6]:    the
66
        [7]:    lazy
67
        [8]:    dog
68

69
After sorting with the default comparer:
70
        [0]:    brown
71
        [1]:    dog
72
        [2]:    fox
73
        [3]:    jumps
74
        [4]:    lazy
75
        [5]:    over
76
        [6]:    quick
77
        [7]:    the
78
        [8]:    The
79

80
After sorting with the reverse case-insensitive comparer:
81
        [0]:    the
82
        [1]:    The
83
        [2]:    quick
84
        [3]:    over
85
        [4]:    lazy
86
        [5]:    jumps
87
        [6]:    fox
88
        [7]:    dog
89
        [8]:    brown 
90
*/

 

怎么樣,大家看出來了吧,其實(shí)在這段代碼里,ArrayList相當(dāng)于Strategy模式中的Context(應(yīng)用場(chǎng)景)部分,而IComparer相當(dāng)于Strategy(抽象策略類)部分,myReverserClass相當(dāng)于ConcreteStrategy(具體策略類)部分。我們這里拋開myReverserClass類的Compare方法如何具體實(shí)現(xiàn)不談,我們只要知道這是一個(gè)具體策略類,它提供了應(yīng)用場(chǎng)景需要的具體算法,它實(shí)現(xiàn)了抽象策略類接口,而應(yīng)用場(chǎng)景通過抽象策略類動(dòng)態(tài)調(diào)用到了具體策略類中的算法。哈!所以這是一個(gè)十分典型的Strategy模式的應(yīng)用。

基于這個(gè)符合Strategy模式的結(jié)構(gòu),我們還可以提供很多種自定義的具體策略類的實(shí)現(xiàn),只要這些類實(shí)現(xiàn)了IComparer接口,就可以在運(yùn)行時(shí)動(dòng)態(tài)設(shè)置給ArrayList類的Sort方法,在Sort方法中會(huì)根據(jù)具體策略類實(shí)現(xiàn)的比較算法規(guī)則來對(duì)ArrayList中的數(shù)據(jù)進(jìn)行排序。

最后一個(gè)設(shè)計(jì)原則

關(guān)于Strategy模式的故事講到這里,應(yīng)該基本OK啦!下面我們?cè)倭男└邔哟蔚臇|西。什么是更高層次的東西?嘿!當(dāng)然是設(shè)計(jì)原則了!在前面總結(jié)Strategy模式的優(yōu)點(diǎn)的時(shí)候我們提到過,Strategy模式不僅保留了繼承的優(yōu)點(diǎn),而且還提供了更靈活的擴(kuò)展能力。為什么會(huì)這樣呢?Strategy模式是怎么做到這一點(diǎn)的呢?哈!這是因?yàn)樗?#8220;上面有人”??!誰啊?它就是我們下面要介紹的重量級(jí)設(shè)計(jì)原則:

Favor composition over inheritance.(優(yōu)先使用對(duì)象組合,而非類繼承)

關(guān)于組合和繼承,我們只要這樣來理解即可:組合是一種“HAS-A”關(guān)系,而繼承是一種“IS-A”關(guān)系。很明顯“HAS-A”要比“IS-A”更靈活一些。也就是說在創(chuàng)建系統(tǒng)的時(shí)候,我們應(yīng)該優(yōu)先使用對(duì)象組合,因?yàn)樗粌H可以給你提供更多靈活性和擴(kuò)展性,而且還使你可以在運(yùn)行時(shí)改變行為(組合不同的對(duì)象),這簡(jiǎn)直是酷斃了!但是也不是說繼承就是不能用,只是說應(yīng)該把繼承應(yīng)用在相對(duì)更穩(wěn)定,幾乎沒有變化的地方,例如前面的Duck類里的Swim()方法,因?yàn)榭梢钥隙ㄋ续喿右欢ǘ紩?huì)游泳,所以就沒有必要給這個(gè)行為提供基于Strategy模式的實(shí)現(xiàn)方式,因?yàn)槟菢幼龀耸浅绦蚋鼜?fù)雜以外,沒有什么意義。

BULLET POINTS

l        Knowing the OO basics does not make you a good OO designer.

l        Good OO designs are reusable,extensible and maintainable.

l        Patterns show you how to build systems with good OO design qualities.

l        Patterns are proven object oriented experience.

l        Patterns don’t give you code,they give you general solutions to design problems.You apply them to your specific application.

l        Patterns aren’t invented,they are discovered.

l        Most patterns and principles address issues of change in software.

l        Most patterns allow some part of a system to vary independently of all other parts.

l        We often try to take what varies in a system and encapsulate it.

l        Patterns provide a shared language that can maximize the value of your communication with other developers.

作者

王曉亮/Justin

MSN:xiaoliang203@hotmail.com

Mail:xiaoliang.justin@gmail.com

參考資料

UML和模式應(yīng)用》

《敏捷軟件開發(fā)—原則、模式與實(shí)踐》

Head First Design Patterns

李建忠老師的《C#面向?qū)ο笤O(shè)計(jì)模式縱橫談系列課程》

posted on 2007-02-06 00:42 Justin 閱讀(19997) 評(píng)論(90)  編輯 收藏 所屬分類: Design PatternsOOAD&UML

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
設(shè)計(jì)模式學(xué)習(xí)筆記(一)——面向?qū)ο笤O(shè)計(jì)模式與原則
【設(shè)計(jì)模式】設(shè)計(jì)原則--面向接口編程你理解的對(duì)嗎?
JAVA設(shè)計(jì)模式之策略模式 - Strategy
HeadFirst設(shè)計(jì)模式讀書筆記之策略模式
java常用設(shè)計(jì)模式
設(shè)計(jì)模式之策略模式示例
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服