日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

設(shè)計模式學(xué)習(xí)筆記(一)——面向?qū)ο笤O(shè)計模式與原則

 skywood 2007-08-06

 今天聽了《C#面向?qū)ο笤O(shè)計模式縱橫談(1):面向?qū)ο笤O(shè)計模式與原則》課程??偨Y(jié)了一些筆記。
 首先介紹了什么是設(shè)計模式:設(shè)計模式描述了軟件設(shè)計過程中某一類常見問題的一般性的解決方案。
 下面主要討論面向?qū)ο笤O(shè)計模式。
 面向?qū)ο笤O(shè)計模式描述了類與相互通信的對象之間的組織關(guān)系。目的是應(yīng)對變化、提高復(fù)用、減少改變。
 那到底什么是對象:
  1、從概念層面講,對象是某種擁有職責(zé)的抽象;
  2、從規(guī)格層面講,對象是一系列可以被其他對象使用的公共接口;
  3、從語言實(shí)現(xiàn)層面來看,對象封裝了代碼和數(shù)據(jù)(也就是行為和狀態(tài))。
  對于這三點(diǎn),我理解最深的應(yīng)該是第三點(diǎn)。這可能和我把大多精力放在了代碼實(shí)現(xiàn)上有關(guān),然而忽略了編程的的思想。如果我們拋開代碼的實(shí)現(xiàn)來看對象的概念,那 么它應(yīng)該就像一個具體的物體,比如說:榔頭,從概念層面講,榔頭有它的職責(zé),也就是它是做什么用的(用來砸釘子,當(dāng)然還會有其他用途,如防身),從規(guī)格層 面講,比如人使用榔頭砸釘子。
 面向?qū)ο蟮脑O(shè)計模式有三大原則:
  1、這對接口編程,而不是針對實(shí)現(xiàn)編程。在知道設(shè)計模式之前,我對接 口的出現(xiàn)很不理解。不明白為什么這個什么都不能實(shí)現(xiàn)的東西會存在,當(dāng)然,也對多態(tài)表示茫然。實(shí)際上我是還沒有理解面向?qū)ο缶幊痰乃枷?。在對設(shè)計模式略有了 解后發(fā)現(xiàn)接口的確是一個好東西,用它實(shí)現(xiàn)多態(tài)的確減少了代碼的修改。
 比如說在《Head First Design Patterns》中有一個例子,說一個有關(guān)鴨子的游戲。游戲當(dāng)中有很多種的鴨子,如:野鴨,木頭鴨,鴨子模型。我們首先會想到做一個抽象類: abstract class Duck,Duck當(dāng)中有很多的抽象屬性和方法,如quack。我們用子類繼承的時候都會實(shí)例化這個方法。
 public abstract class Duck
 {
  public abstract void quack()
 }
 
 public class MallardDuck:Duck
 {
  public override void quack()
  {
   Console.Write("I can quack");
  }
 }
當(dāng) 程序成型后,我們有了很多種鴨子,突然,我們發(fā)現(xiàn)有的鴨子會飛,我們會在Duck中在加上一個抽象方法abstract void fly();于是我們不得不在所有的子類當(dāng)中添加fly的實(shí)現(xiàn),有人會說,如果我們在Duck中直接添加fly的實(shí)現(xiàn),不久不用在子類中添加實(shí)現(xiàn)了嗎?那 老板就該問你:你見過木頭鴨子滿天飛(哦,天??!木頭鴨子也飛起來了,這是什么世界!)。對不起老板,現(xiàn)在咱們都見到了。
 這時我們換一種想法,如果我們把這些方法都提取出來,把它變成Duck的成員,好像問題就會簡單些。
 哈哈,好像扯的有點(diǎn)遠(yuǎn)了,現(xiàn)在回來接著記我的筆記。
  2、優(yōu)先使用對象組合,而不是類的繼承。
 這就使說多使用“has a”,少使用“is a”,哈哈,我又想說回剛才的例子。換個角度考慮Duck及其功能,我們設(shè)計一個fly的接口和一些具體的飛行方法。
 public interface FlyBehavior
 {
  void fly();
 }

 public class FlyWithWing:FlyBehavior
 {
  public void fly()
  {
   Console.Write("I can fly\n");
  }
 }

 public class FlyNoWay:FlyBehavior
 {
  public void fly()
  {
   Console.Write("I can‘t fly\n");
  }
 } 
 好了,對于Duck來說,現(xiàn)在它應(yīng)該有一個(has a)fly的方法
 public abstract class Duck
 {
  public Duck()
  {}
  public FlyBehavior flybehavior; 
 }
 現(xiàn)在我們再來實(shí)現(xiàn)兩種鴨子
 public class ModelDuck:Duck
 {
  public ModelDuck()
  {
   flybehavior = new FlyNoWay();
  }
 }
 
 public class MallardDuck:Duck
 {
  public MallardDuck()
  {
   flybehavior = new FlyWithWing();
  }
 }
 這樣如果要是在加上某種行為的話,我們就不必在每一種鴨子上下功夫。把注意力放在我們關(guān)心的鴨子品種上(別太使勁關(guān)注,小心禽流感,“阿切!”)。
  3、封裝變化點(diǎn),實(shí)現(xiàn)松耦合,這點(diǎn)不用多說了。
 課程中提到,編碼當(dāng)中的設(shè)計模式使用不是我們在編程之初就定下來的,應(yīng)該是重構(gòu)得到設(shè)計模式(Refactoring to Patterns)。哦,原來是這樣,也好理解。在編碼中遇到問題,然后想想應(yīng)對方式。哈哈,我原來認(rèn)為開始編程時就指定我們用什么設(shè)計模式呢。
 下面說說設(shè)計原則:
  1、單一職責(zé)原則(SRP):一個類應(yīng)僅有一個引起它變化的原因。
  2、 開放封閉原則(OCP):類模塊應(yīng)可擴(kuò)展,不可修改。這里要說明一下,擴(kuò)展和修改是不同的。比如:我們要在加一種ModelDuck,那么我們寫一個 ModelDuck的類繼承Duck,這叫擴(kuò)展,不是修改。什么是修改,就好像我們開始說的那種作法,為了加一個fly的功能,我們要把所有的子類中加入 不同的實(shí)現(xiàn),這叫修改。
  3、Liskov替換原則:子類可替換基類。
  4、依賴倒置原則:高層模塊不依賴于低層模塊,二者都依賴于抽象。還是剛才的例子:Duck是一個高層模塊,fly是低層模塊。Duck不依賴于fly,高層模塊的改變慢,而低層模塊的改變慢。
     抽象不應(yīng)依賴于實(shí)現(xiàn)細(xì)節(jié),實(shí)現(xiàn)細(xì)節(jié)應(yīng)依賴于抽象。fly是一個抽象,它不依賴如何飛行。
  5、接口隔離原則:不強(qiáng)迫客戶程序依賴于它們不用的方法(有道理,木頭鴨子不會飛為什么要讓它實(shí)現(xiàn)飛的功能。)
  最后有人提問接口和抽象類的區(qū)別:
   接口可以多繼承,抽象類只能但繼承。接口定義組件間的合同。使用抽象類為一個is a的關(guān)系。

posted on 2006-03-29 17:00 KiddLee 閱讀(1979) 評論(12)  編輯 收藏 引用 網(wǎng)摘 所屬分類: 設(shè)計模式

FeedBack:
# 
建議作者使用摘要方式發(fā)布, 請參考: http://www.cnblogs.com/dudu/articles/52480.aspx 第四項(xiàng)。  回復(fù)  更多評論
  
# re: 設(shè)計模式學(xué)習(xí)筆記(一)——面向?qū)ο笤O(shè)計模式與原則 2006-03-29 17:07 Terrylee
呵呵,總結(jié)得不錯

有一個筆誤:應(yīng)該是“開放封閉原則”,不是“開發(fā)封閉原則”  回復(fù)  更多評論
  
# re: 設(shè)計模式學(xué)習(xí)筆記(一)——面向?qū)ο笤O(shè)計模式與原則 2006-03-29 17:55 csdn shit!
這個講師對抽象類理解的不到位。
其實(shí)在實(shí)際編程中抽象類的應(yīng)用不比接口少。原因在于它既可以定義供繼承的方法(避免重復(fù)),又可以象接口一樣規(guī)定必須實(shí)現(xiàn)的方法。ms也是對抽象類推崇備至的。  回復(fù)  更多評論
  
# re: 設(shè)計模式學(xué)習(xí)筆記(一)——面向?qū)ο笤O(shè)計模式與原則 2006-03-29 23:13 Dflying Chen
接口實(shí)現(xiàn)契約,是不變的。繼承實(shí)現(xiàn)擴(kuò)展與重用,是可變的。  回復(fù)  更多評論
  
# re: 設(shè)計模式學(xué)習(xí)筆記(一)——面向?qū)ο笤O(shè)計模式與原則 2006-04-22 14:50 ivan
其實(shí)上面那個例子舉得不是很好,抽象類應(yīng)該是可實(shí)現(xiàn)抽象方法或都不實(shí)現(xiàn)抽象方法的,如果有的鴨子要飛那么就調(diào)用抽象類中的fly的方法.這樣都不用去修改其它子類呀,為什么要說成要修改其它子類的呢~!  回復(fù)  更多評論
  
# re: 設(shè)計模式學(xué)習(xí)筆記(一)——面向?qū)ο笤O(shè)計模式與原則 2006-04-22 16:08 kid_li
@ivan
抽象類中的抽象方法如果不被繼承的子類實(shí)現(xiàn),那么子類還是一個抽象類,也就無法實(shí)例化,從模型的角度看,如果某個屬性或方法與這個模型的本身沒有關(guān)系,那么這個模型為什么要擁有這個屬性或方法呢?例如:木鴨子不會飛,就不應(yīng)該它實(shí)現(xiàn)fly的方法。  回復(fù)  更多評論
  
# re: 設(shè)計模式學(xué)習(xí)筆記(一)——面向?qū)ο笤O(shè)計模式與原則 2006-04-22 16:19 kid_li
@ivan
上面說的例子是游戲的設(shè)計者在第一版游戲中沒有用到鴨子飛行的方法,但是在第二版游戲中需要添加這個功能,如果在抽象類中加入fly的話,所有的 子類都要對這個方法就行實(shí)現(xiàn)(不會飛的鴨子類不應(yīng)該要變動),這是因?yàn)槔^承的依賴性。如果我們改成“has a”的關(guān)系,那么問題就簡單多了  回復(fù)  更多評論
  
# 請教幾個問題 2006-05-16 16:25 ssgrl
有幾個設(shè)計模式方面的問題想請教一下:

1、JAVA語言不支持泛型技術(shù),那么如何在JAVA中構(gòu)造同構(gòu)容器?請簡述思路。

2、當(dāng)我們設(shè)計一個應(yīng)用程序的用戶界面時,某些情況下可以使用合成模式,請舉一例。

3、在足球賽中,參與者有球隊(duì),球員,教練,比賽,裁判等。一個球隊(duì)由11名球員和一個教練組成(為簡化,我們不考慮替補(bǔ)),每場比賽有兩個隊(duì), 一位裁判(為簡化,我們僅考慮主裁判),整個比賽有N場比賽(為簡化,我們不考慮小組賽,淘汰賽等細(xì)節(jié)區(qū)別),請對這個案例建立對象模型(描述建立哪些類 或?qū)ο螅舜说年P(guān)系)。請使用文字描述,并畫出UML圖。

4、為保護(hù)公眾安全,英國決定部署交通系統(tǒng)聯(lián)合防護(hù)網(wǎng):如果任何地方發(fā)生了某類可疑事件,這個消息將會被立即發(fā)送給網(wǎng)絡(luò)內(nèi)所有機(jī)構(gòu),注意:網(wǎng)絡(luò)內(nèi) 的機(jī)構(gòu)是動態(tài)變化的,可以加入或者退出,可疑事件的類型也是可能動態(tài)擴(kuò)展的。請使用面向?qū)ο蟮脑O(shè)計模式,簡述此類需求的解決方案。
  回復(fù)  更多評論
  
# re: 設(shè)計模式學(xué)習(xí)筆記(一)——面向?qū)ο笤O(shè)計模式與原則 2006-05-17 11:09 kid_li
@ssgrl
1、聽了一些C#2.0的東西,其中提到了Java中的范型實(shí)現(xiàn),據(jù)說在Java1.5中已實(shí)現(xiàn),但并不是在虛擬機(jī)層面上,而是編譯器層上的,也 只是用java.lang中的object類型進(jìn)行類似裝箱拆箱,也就是對類型的轉(zhuǎn)換。但是這種方式有一定的危險性,而且性能不是很理想。危險性在于,在 將object類型轉(zhuǎn)換成其他類型的時候,你必須確定object對象能夠轉(zhuǎn)換,性能不高是因?yàn)椋@種轉(zhuǎn)換畢竟不如范型的類型參數(shù)效率高。
當(dāng)然,對于Java,我了解得不多,以后我會加強(qiáng)這方面的學(xué)習(xí)。
2、對于合成模式,大概看了一下,給我很重要的感覺是它可以將“一對多”的關(guān)系轉(zhuǎn)化為“一對一”的關(guān)系解決。我覺得,類似樹形的實(shí)現(xiàn)可以采用這種 模式。我是剛開始學(xué)習(xí)設(shè)計模式,設(shè)計模式的Blog也在繼續(xù)寫,今后寫到合成模式時,我想我會有更深的理解,到時候,我會再好好想想你的問題。
對于你省下的問題,比較具體,現(xiàn)在工作有點(diǎn)忙。如果不急,近期我會發(fā)Email給你我的想法  回復(fù)  更多評論
  
# re: 設(shè)計模式學(xué)習(xí)筆記(一)——面向?qū)ο笤O(shè)計模式與原則 2006-06-04 21:57 main
最近一直在聽下載的視頻資料,多交流,一起分享!  回復(fù)  更多評論
  
# re: 設(shè)計模式學(xué)習(xí)筆記(一)——面向?qū)ο笤O(shè)計模式與原則 2006-07-18 13:59 大雁
作 者提到:"突然,我們發(fā)現(xiàn)有的鴨子會飛,我們會在Duck中在加上一個抽象方法abstract void fly();于是我們不得不在所有的子類當(dāng)中添加fly的實(shí)現(xiàn)" ,這里我有點(diǎn)不解,既然是某些鴨子會飛,如果加了抽象方法那不是所有的實(shí)現(xiàn)子類都要實(shí)現(xiàn)飛的方法?
作者還提到“如果我們把這些方法都提取出來,把它變成Duck的成員” 那不所有的鴨子子類都有飛的屬性?
我覺得在這里可以單獨(dú)設(shè)計一個接口,會飛的鴨子就實(shí)現(xiàn)這個接口不就行了  回復(fù)  更多評論
  
# re: 設(shè)計模式學(xué)習(xí)筆記(一)——面向?qū)ο笤O(shè)計模式與原則 2006-07-18 14:36 kid_li
@大雁
例子是為了說明在抽象類中加入抽象方法或方法,以造成了對于子模塊中出現(xiàn)的一些問題,也就是繼承增加了父子模塊的偶合度。設(shè)計模式中希望用組合的方式代替繼承方式,以減小模塊間的偶合。
對于第一個問題,哈哈,子類繼承父類后,要實(shí)現(xiàn)父類中的所有抽象方法,否則此子類還是一個抽象類。
對于第二個問題,你說的有道理,設(shè)計模式中提倡面向接口編程  回復(fù)  更多評論

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多