日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

笔记:Head First设计原则和设计模式

發(fā)布時(shí)間:2023/12/20 asp.net 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 笔记:Head First设计原则和设计模式 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Head First 設(shè)計(jì)原則和設(shè)計(jì)模式

      • 原則一:封裝變化。找出應(yīng)用中可能會(huì)變化之處,把它獨(dú)立出來,不要和那些不需要變化的混在一起
      • 原則二:針對(duì)接口編程,而不是針對(duì)實(shí)現(xiàn)編程
      • 原則三:多用組合,少用繼承
      • 策略模式:定義了算法族,分別封裝起來,讓它們之間可以互相替換,此模式讓算法的變化獨(dú)立于使用算法的客戶。
      • 觀察者模式:定義了對(duì)象之間的一對(duì)多依賴,當(dāng)一個(gè)對(duì)象改變狀態(tài)時(shí),它的所有依賴者都會(huì)收到通知并自動(dòng)更新。
      • 原則四:為了交互對(duì)象之間的松耦合設(shè)計(jì)而努力。
      • 原則五:類應(yīng)該對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。
      • 裝飾者模式:動(dòng)態(tài)地將責(zé)任附加到對(duì)象上。若要擴(kuò)展功能,裝飾者提供了比繼承更有彈性的替代方案。
      • 工廠模式
          • 簡(jiǎn)單工廠模式
          • 工廠方法模式:定義了一個(gè)創(chuàng)建對(duì)象的接口,但由子類決定要實(shí)例化的類是哪一個(gè)。工廠方法讓類的實(shí)例化推遲到子類。
      • 依賴倒置原則:要依賴抽象,不要依賴具體類。
          • 抽象工廠:提供一個(gè)接口,用于創(chuàng)建相關(guān)或依賴對(duì)象的家族,而不需要明確指定具體類。
      • 單件模式:確保一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn)。
        • 多例模式
      • 命令模式:將“請(qǐng)求”封裝成對(duì)象,以便使用不同的請(qǐng)求、隊(duì)列或者日志來參數(shù)化其他對(duì)象。命令模式也支持可撤消的操作。
      • 適配器模式:將一個(gè)類的接口,轉(zhuǎn)換成客戶期望的另一個(gè)接口。適配器讓原本接口不兼容的類可以合作無間。
      • 外觀模式:提供一個(gè)統(tǒng)一的接口,用來訪問子系統(tǒng)中的一群接口。外觀定義了一個(gè)高層接口,讓子系統(tǒng)更容易使用。
      • 原則六:最少知識(shí)原則,只和你的密友談話。(迪米特法則)
      • 模版方法模式:在一個(gè)方法中定義一個(gè)算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變算法結(jié)構(gòu)的情況下,重新定義算法中的某些步驟。
      • 原則七:好萊塢原則,別調(diào)用(打電話給)我們,我們會(huì)調(diào)用(打電話給)你。
      • 迭代器模式:提供一種方法順序訪問一個(gè)聚合對(duì)象中的各個(gè)元素,而又不暴露其內(nèi)部的表示。
      • 原則八:單一責(zé)任(基本原則):一個(gè)類應(yīng)該只有一個(gè)引起變化的原因。
      • 組合模式:允許你將對(duì)象組合成樹形結(jié)構(gòu)來表現(xiàn)“整體/部分”層次結(jié)構(gòu)。組合能讓客戶以一致的方式處理個(gè)別對(duì)象以及對(duì)象組合。
      • 狀態(tài)模式:允許對(duì)象在內(nèi)部狀態(tài)改變時(shí)改變它的行為,對(duì)象看起來好像修改了它的類。
      • 代理模式:為另一個(gè)對(duì)象提供一個(gè)替身或占位符以控制對(duì)這個(gè)對(duì)象的訪問。

原則一:封裝變化。找出應(yīng)用中可能會(huì)變化之處,把它獨(dú)立出來,不要和那些不需要變化的混在一起

封裝變化,使其更具有彈性。eg:把鴨子中容易變化的fly()和quack()分別從duck類中獨(dú)立出來

哪些因素導(dǎo)致你必須改變你的程序?

  • 我的客戶或用戶決定他們想要其他一些東西或新功能
  • 我公司決定使用另一個(gè)數(shù)據(jù)庫,并且從使用不同數(shù)據(jù)格式的另一個(gè)支持商購買數(shù)據(jù)
  • 技術(shù)改變,所以我們不得不更新我們的代碼取使用新的協(xié)議
  • 想要重構(gòu)系統(tǒng)使其更好

原則二:針對(duì)接口編程,而不是針對(duì)實(shí)現(xiàn)編程

利用接口代表每個(gè)行為,行為的每個(gè)實(shí)現(xiàn)都要實(shí)現(xiàn)其中一個(gè)接口。這樣,鴨子就不需要知道行為的具體實(shí)現(xiàn)了。
“針對(duì)接口編程”真正的意思是針對(duì)超類型編程,可以利用多態(tài)。多態(tài):聲明的變量類型應(yīng)該時(shí)一個(gè)超類,通常是一個(gè)接口的抽象類,所以分配給這些變量的對(duì)象可以是父類的任何具體實(shí)現(xiàn),這意味著類聲明他們不需要知道具體對(duì)象類型。

原則三:多用組合,少用繼承

“有一個(gè)”可能比“是一個(gè)”更好

策略模式:定義了算法族,分別封裝起來,讓它們之間可以互相替換,此模式讓算法的變化獨(dú)立于使用算法的客戶。



什么時(shí)候使用策略模式?

  • 很多相關(guān)類僅僅行為不同
  • 你需要一個(gè)算法的不同變體
  • 算法使用的數(shù)據(jù)用戶不應(yīng)該知道(避免暴露內(nèi)部數(shù)據(jù)結(jié)構(gòu))
  • 類定義了許多行為,這些行為在其操作中顯示為多個(gè)條件語句

什么是設(shè)計(jì)模式:

  • 記錄設(shè)計(jì)面向?qū)ο筌浖慕?jīng)驗(yàn)作為設(shè)計(jì)模式
  • 每個(gè)設(shè)計(jì)模式系統(tǒng)性地命名,解釋以及評(píng)估一個(gè)重要的且重復(fù)出現(xiàn)在面向?qū)ο笙到y(tǒng)中的設(shè)計(jì)
  • 目標(biāo)是去捕獲設(shè)計(jì)經(jīng)驗(yàn),用一種人們可以高效使用的形式
  • 每個(gè)模式描述了一個(gè)在我們的環(huán)境中反復(fù)出現(xiàn)的問題,然后描述了這個(gè)問題的解決方案的核心,這樣您就可以將這個(gè)解決方案重復(fù)使用一百萬次,而不必重復(fù)使用相同的方法兩次

設(shè)計(jì)模式的好處:

  • 設(shè)計(jì)模式為你和其他開發(fā)者提供一個(gè)共享詞匯表
  • 通過讓你在模式層面思考,而不是基本對(duì)象層面,提升你關(guān)于架構(gòu)的思考

如何使用設(shè)計(jì)模式?

  • 庫和框架
  • DP幫助我們構(gòu)建的程序更加可維護(hù)和可擴(kuò)展
  • DP首先進(jìn)入你的大腦

設(shè)計(jì)模式4元素:

  • 模式名:用一兩個(gè)詞描述一個(gè)設(shè)計(jì)問題,解決方案和結(jié)論
  • 問題:描述什么時(shí)候取應(yīng)用模式
  • 解決方案:描述組成設(shè)計(jì)的元素,元素之間的關(guān)系,責(zé)任和合作
  • 結(jié)論:應(yīng)用模式的結(jié)果和權(quán)衡

觀察者模式:定義了對(duì)象之間的一對(duì)多依賴,當(dāng)一個(gè)對(duì)象改變狀態(tài)時(shí),它的所有依賴者都會(huì)收到通知并自動(dòng)更新。


上圖中,具體觀察者持有主題的引用,為了在主題那注冊(cè)成為觀察者。

使用Java的Observable和Observer接口實(shí)現(xiàn)觀察者模式
WeatherData.java

import java.util.Observable; import java.util.Observer; // 不再需要去持有observers,也不需要管理他們的注冊(cè)和移除,父類Observable會(huì)處理他們 public class WeatherData extends Observable{privatate float temperature;privatate float humidity;privatate float pressure;public WeatherData() { // 繼承Observable之后不再需要?jiǎng)?chuàng)建保持Observers的數(shù)據(jù)結(jié)構(gòu)}public void messurementsChanged() {setChanged(); // 在通知觀察者之前先setChanged()來表明狀態(tài)已經(jīng)改變notifyObservers(); // 沒有傳數(shù)據(jù)對(duì)象,說明用的PULL模型}public void setMeasurements(float temperature, float humidity, float pressure) {this.temperature = temperature;this.humidity = humidity;this.pressure = pressure;messurementsChanged();}public float getTemperature() {return temperature;}public float getHumidity() {return humidity;}public float getPressure() {return pressure;}}

CurrentConditionsDisplay.java

import java.util.Observable; import java.util.Observer;public class CurrentConditionsDisplay implements Observer, DispalyElement{Observable observable;private float temperature;private float humidity;public CurrentConditionsDisplay(Observable observable){this.observable = observable; //構(gòu)造器持有一個(gè)Observable,使用去添加當(dāng)前對(duì)象為Observerobservable.addObserver(this);}public void update(Observable obs, Object arg){if(obs instamceof WeatherData){ // 確保Observable是WeatherData類型WeatherData weatherData = (WeatherData)obs;this.temperature = weatherData.getTemperature();this.humidity = weatherData.getHumidity();display();}}public void dispaly(){System.out.println(temperature + humidity)}}

當(dāng)兩個(gè)對(duì)象之間松耦合,它們依然可以交互,但不清楚彼此的細(xì)節(jié)。觀察者提供了一種對(duì)象設(shè)計(jì),讓主題和觀察者之間松耦合。
任何時(shí)候都可以增加新觀察者,因?yàn)橹黝}唯一依賴的東西是實(shí)現(xiàn)Observer接口的對(duì)象列表。
改變主題或觀察者其中一方,并不會(huì)影響另一方。

原則四:為了交互對(duì)象之間的松耦合設(shè)計(jì)而努力。

原則五:類應(yīng)該對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。

遵循開放-關(guān)閉原則,通常會(huì)引入新的抽象層次,增加代碼的復(fù)雜度。需要把注意力集中在設(shè)計(jì)中最有可能改變的地方,然后應(yīng)用開發(fā)-關(guān)閉原則。裝飾者模式完全遵循開放-關(guān)閉原則。

裝飾者模式:動(dòng)態(tài)地將責(zé)任附加到對(duì)象上。若要擴(kuò)展功能,裝飾者提供了比繼承更有彈性的替代方案。




裝飾者類圖

星巴茲實(shí)例類圖

裝飾者繼承被裝飾者而不使用組合?繼承是因?yàn)檠b飾者和被裝飾者必須是一樣的類型,這里利用繼承達(dá)到“類型匹配”,而不是利用繼承獲得“行為”。那么行為從哪來?當(dāng)將裝飾者與組件組合時(shí),就是加入新行為,得到的新行為不是繼承自超類,而是組合對(duì)象來的。

具體裝飾者類


裝飾者模式在JAVA中的應(yīng)用


寫一個(gè) Lower Case Input Stream 類

public class LowerCaseInputStream extends FilterInputStream {public LowerCaseInputStream(InputStream in) {super(in);}public int read() throws IOException {int c = in.read();return (c == -1 ? c : Character.toLowerCase((char)c));}public int read(byte[] b, int offset, int len) throws IOException {int result = in.read(b, offset, len);for (int i = offset; i < offset+result; i++) {b[i] = (byte)Character.toLowerCase((char)b[i]);}return result;} }

工廠模式

簡(jiǎn)單工廠模式

簡(jiǎn)單工廠把實(shí)例化代碼放到工廠里,并不僅是轉(zhuǎn)移問題到另一個(gè)對(duì)象(封裝變化),因?yàn)楹?jiǎn)單工廠類可以有多個(gè)客戶。
靜態(tài)工廠不需要使用創(chuàng)建對(duì)象的方法來實(shí)例化對(duì)象,但缺點(diǎn)是不能通過繼承來改變創(chuàng)建方法的行為。

簡(jiǎn)單工廠模式披薩店實(shí)例

工廠方法模式:定義了一個(gè)創(chuàng)建對(duì)象的接口,但由子類決定要實(shí)例化的類是哪一個(gè)。工廠方法讓類的實(shí)例化推遲到子類。

通過讓子類決定該創(chuàng)建的對(duì)象是什么,來達(dá)到將對(duì)象創(chuàng)建的過程封裝的目的。
在超類中定義工廠方法來處理對(duì)象的創(chuàng)建,并將行為封裝在子類中。這樣,超類代碼就和子類對(duì)象創(chuàng)建解耦了。

注意,子類決定要實(shí)例化的類是哪個(gè),并不是指模式允許子類本身在運(yùn)行時(shí)做決定,而是選擇了使用哪個(gè)子類,自然就決定了實(shí)際創(chuàng)建的產(chǎn)品是什么。

工廠方法披薩店實(shí)例

  • 只有一個(gè)ConcreteCreator時(shí),工廠方法模式優(yōu)點(diǎn): 幫助我們將產(chǎn)品的“實(shí)現(xiàn)”從“使用”中解耦,如果增加產(chǎn)品或改變產(chǎn)品的實(shí)現(xiàn),Creator并不會(huì)受到影響。
  • 各自的ConcreteCreator看起來像利用簡(jiǎn)單工廠創(chuàng)建的? 用法不同。雖然每個(gè)具體商店實(shí)現(xiàn)看起來像簡(jiǎn)單工廠,但這里具體商店是擴(kuò)展自一個(gè)類,此類有一個(gè)抽象方法createPizza(),由每個(gè)具體商店自行負(fù)責(zé)createPizza()方法的行為。而簡(jiǎn)單工廠中,工廠是另一個(gè)由Pizzasfore使用的對(duì)象。

依賴倒置原則:要依賴抽象,不要依賴具體類。

和“針對(duì)接口編程,不針對(duì)實(shí)現(xiàn)編程”很相似,但這里更強(qiáng)調(diào)抽象,這個(gè)原則說明:不能讓高層組件依賴低層組件,而且,不管高層或低層組件,都應(yīng)該依賴于抽象。

  • 應(yīng)用工廠方法后,高層組件(PizzaStore)和低層組件(具體披薩)都依賴了Pizza抽象
  • 倒置思考方式:不要從上到下思考披薩店應(yīng)該實(shí)現(xiàn)哪些披薩,而是從下往上思考各種披薩都是披薩,應(yīng)該共享一個(gè)pizza接口。
  • 避免違反依賴倒置指導(dǎo)方針:
  • 變量不可以持有具體類的引用:使用new就會(huì)持有具體類引用,可以改用工廠來避免;
  • 不要讓類派生自具體類:派生自具體類就會(huì)依賴具體類,應(yīng)派生自接口。
  • 不要覆蓋基類中已實(shí)現(xiàn)的方法:如果覆蓋,基類就不是真正適合被繼承的抽象。基類中已實(shí)現(xiàn)的方法,應(yīng)該由所有子類共享。

方針只是指導(dǎo)作用,如果類不容易改變,可直接實(shí)例化。

DIP的“倒置”在哪?

  • 依賴倒置原則中的“倒置”使因?yàn)樗D(zhuǎn)換你典型地對(duì)OO設(shè)計(jì)的思維方式
  • 自上而下的依賴關(guān)系圖會(huì)反轉(zhuǎn)自身,高級(jí)和低級(jí)模塊現(xiàn)在都依賴于抽象。
抽象工廠:提供一個(gè)接口,用于創(chuàng)建相關(guān)或依賴對(duì)象的家族,而不需要明確指定具體類。


抽象工廠模式披薩店實(shí)例

注意到:抽象工廠的每個(gè)方法實(shí)際上看起來都像工廠方法。抽象工廠的方法經(jīng)常以工廠方法的方式實(shí)現(xiàn),接口內(nèi)的每個(gè)方法負(fù)責(zé)創(chuàng)建一個(gè)具體產(chǎn)品,同時(shí)利用抽象工廠的子類來提供具體的做法。
工廠方法和抽象工廠:
1)都負(fù)責(zé)創(chuàng)建對(duì)象
2)工廠方法用繼承,通過子類來創(chuàng)建對(duì)象,將客戶從具體類型中解耦。
3)抽象工廠用組合,創(chuàng)建一個(gè)產(chǎn)品家族的抽象類型,其子類定義了產(chǎn)品被產(chǎn)生的方法,將客戶從具體產(chǎn)品中解耦。
4)抽象工廠相比工廠方法,優(yōu)點(diǎn)是可以把一群相關(guān)的產(chǎn)品集合起來,缺點(diǎn)是加入新產(chǎn)品就必須改變接口(擴(kuò)展性較差)。
5)當(dāng)需要?jiǎng)?chuàng)建產(chǎn)品家族和想讓制造的相關(guān)產(chǎn)品集合起來時(shí),使用抽象工廠
6)只是想把客戶代碼從需要實(shí)例化的具體類中解耦時(shí),使用工廠方法

單件模式:確保一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn)。

多件?


在使用多線程后,單件模式可能出現(xiàn)問題,此時(shí)應(yīng)該把getInstance()變成同步(synchronized)方法。

但每次都進(jìn)行同步會(huì)造成性能損失,其實(shí),只需要在第一次執(zhí)行此方法時(shí)進(jìn)行同步即可。
雙重檢查加鎖

能不能繼承單件類?
構(gòu)造器私有,不能用私有構(gòu)造器擴(kuò)展類,必須把構(gòu)造器改成公開的或受保護(hù)的,但這樣就不能算單件了。

多例模式

所謂多例(Multiton Pattern)實(shí)際上就是單例模式的自然推廣,屬于對(duì)象創(chuàng)建類型的模式,多例模式其實(shí)就是限制了對(duì)象的數(shù)量,并且有可能對(duì)對(duì)象進(jìn)行重復(fù)使用。
特點(diǎn):

  • 多例可以有多個(gè)實(shí)例
  • 多例類必須能夠自我創(chuàng)建并管理自己的實(shí)例,并且向外界提供自己的實(shí)例
  • 多例類場(chǎng)景:
    在java學(xué)習(xí)過程中,有一個(gè)池子的概念一直存在,好比作線程池,數(shù)據(jù)庫連接池,這個(gè)池子是用來對(duì)線程,或者數(shù)據(jù)庫連接對(duì)象進(jìn)行管理的,第一,限制了池子中的對(duì)象數(shù)量,第二就是能夠在使用過程中達(dá)到復(fù)用的效果,線程中的線程在執(zhí)行完畢后,不會(huì)被直接回收掉,而會(huì)切換成等待狀態(tài),等待下一個(gè)任務(wù)提交,執(zhí)行。數(shù)據(jù)庫連接池也是如此,數(shù)據(jù)庫操作在連接的時(shí)候,如果對(duì)數(shù)據(jù)庫操作完畢后,會(huì)把資源釋放,然后等待下一個(gè)數(shù)據(jù)庫操作進(jìn)行連接。這種設(shè)計(jì)其實(shí)是將對(duì)象的應(yīng)用最大化了,避免了每次連接的時(shí)候都需要去創(chuàng)建一個(gè)對(duì)象。造成對(duì)象冗余或者內(nèi)存升高。

    命令模式:將“請(qǐng)求”封裝成對(duì)象,以便使用不同的請(qǐng)求、隊(duì)列或者日志來參數(shù)化其他對(duì)象。命令模式也支持可撤消的操作。

    一個(gè)命令對(duì)象通過在特定接收者上綁定一組動(dòng)作來封裝一個(gè)請(qǐng)求。命令對(duì)象將動(dòng)作和接收者包進(jìn)對(duì)象中,只暴露execute()方法,當(dāng)該方法被調(diào)用時(shí),接收者會(huì)進(jìn)行這些動(dòng)作。
    從外面看,其他對(duì)象不知道究竟哪個(gè)接收者進(jìn)行哪些動(dòng)作,只知道調(diào)用execute()方法就能達(dá)到目的。
    命令對(duì)象

    命令模式類圖


    命令對(duì)象簡(jiǎn)單遙控的Client示例


    **復(fù)雜遙控器(調(diào)用者)**調(diào)用者和接受者之間解耦

    **NoCommand對(duì)象:**空對(duì)象,當(dāng)你不想返回一個(gè)有意義的對(duì)象時(shí),可以返回一個(gè)空對(duì)象。客戶也可以將處理null的責(zé)任轉(zhuǎn)移給空對(duì)象。
    實(shí)現(xiàn)undo撤銷功能


    宏命令


    接收者一定有必要存在嗎?為何命令對(duì)象不直接實(shí)現(xiàn)execute()方法細(xì)節(jié)?
    盡量設(shè)計(jì)“傻瓜”命令對(duì)象,它只懂得調(diào)用一個(gè)接收者的一個(gè)行為。讓調(diào)用者和接收者之間解耦。
    可以通過創(chuàng)建PartyCommand,在它的execute()方法調(diào)用其他命令,來實(shí)現(xiàn)Party模式嗎?
    這樣相當(dāng)于把Party模式“硬編程”到PartyCommand中。利用宏命令可以動(dòng)態(tài)決定PartyCommand是由哪些命令組成,更靈活。
    命令模式應(yīng)用:隊(duì)列請(qǐng)求(工作隊(duì)列類和進(jìn)行計(jì)算的對(duì)象之間解耦)、日志請(qǐng)求

    Java語言使用命令模式實(shí)現(xiàn)AWT/Swing GUI的 委派事件模型 (Delegation Event Model, DEM)
    在AWT/Swing中,Frame、Button等界面組件是請(qǐng)求發(fā) 送者,而AWT提供的事件監(jiān)聽器接口和事件適配器類是抽象命令接口,用戶可以自己寫抽象命令接口的子類來 實(shí)現(xiàn)事件處理,即實(shí)現(xiàn)具體命令類,而在具體命令類中 可以調(diào)用業(yè)務(wù)處理方法來實(shí)現(xiàn)該事件的處理。對(duì)于界面 組件而言,只需要了解命令接口即可,無須關(guān)心接口的實(shí)現(xiàn),組件類并不關(guān)心實(shí)際操作,而操作由用戶來實(shí)現(xiàn)。

    適配器模式:將一個(gè)類的接口,轉(zhuǎn)換成客戶期望的另一個(gè)接口。適配器讓原本接口不兼容的類可以合作無間。

    適配器模式火雞冒充鴨子示例

    萬一系統(tǒng)中新舊并存,舊的部分期望舊接口,但我們已經(jīng)使用新接口編寫了這一部分,這是該怎么辦?
    可以創(chuàng)建一個(gè)雙向適配器,支持兩邊的接口。想創(chuàng)建一個(gè)雙向適配器,就必須實(shí)現(xiàn)所涉及的兩個(gè)接口,這樣可以當(dāng)舊接口,或當(dāng)新接口使用。

    對(duì)象適配器和類適配器使用兩種不同的適配方法(分別是組合與繼承)。兩個(gè)實(shí)現(xiàn)的差異如何影響適配器彈性?
    對(duì)象適配實(shí)現(xiàn)接口,如果方法參數(shù)數(shù)量不同等,可能一些方法無法適配。
    而類適配器使用繼承,如果方法參數(shù)數(shù)量不同,可以通過改寫父類方法來適配。
    適配器模式的應(yīng)用:將枚舉器適配到迭代器


    對(duì)于remove()方法,由于枚舉不支持刪除,因?yàn)槊杜e是一個(gè)“只讀”接口,因此適配器無法實(shí)現(xiàn)一個(gè)有實(shí)際功能的remove()方法,最多只能拋出一個(gè)運(yùn)行時(shí)異常UnsupportedOprationException。

    外觀模式:提供一個(gè)統(tǒng)一的接口,用來訪問子系統(tǒng)中的一群接口。外觀定義了一個(gè)高層接口,讓子系統(tǒng)更容易使用。

    外觀包裝子系統(tǒng)的類,那么需要低層功能的客戶如何接觸這些類?
    外觀沒有“封裝”子系統(tǒng)的類,只是提供簡(jiǎn)化的接口。外觀一個(gè)很好特征:提供簡(jiǎn)化接口的同時(shí),依然將系統(tǒng)完整的功能暴露出來,以供需要的人使用。
    除了提供簡(jiǎn)化接口,外觀模式還允許將客戶實(shí)現(xiàn)從任何子系統(tǒng)中解耦。
    **適配器模式和外觀模式區(qū)別:**外觀和適配器都可以包裝許多類。但適配器的意圖是“改變”接口符合客戶的期望,外觀模式的意圖是提供子系統(tǒng)的一個(gè)簡(jiǎn)化接口。
    外觀模式的家庭影院實(shí)例

    原則六:最少知識(shí)原則,只和你的密友談話。(迪米特法則)

    對(duì)任何對(duì)象,在該對(duì)象的方法內(nèi),只應(yīng)該調(diào)用以下范圍方法:

    • 該對(duì)象本身
    • 被當(dāng)做方法的參數(shù)而傳遞進(jìn)來的對(duì)象
    • 此方法所創(chuàng)建或?qū)嵗娜魏螌?duì)象
    • 對(duì)象的任何組件

      **最少知識(shí)原則缺點(diǎn):**導(dǎo)致更多“包裝”類被制造出來,以處理和其他組件的溝通,導(dǎo)致復(fù)雜度和開發(fā)時(shí)間增加,并降低運(yùn)行時(shí)性能。

    模版方法模式:在一個(gè)方法中定義一個(gè)算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變算法結(jié)構(gòu)的情況下,重新定義算法中的某些步驟。



    hook鉤子

    鉤子被聲明在抽象類中,但只有空的或默認(rèn)的實(shí)現(xiàn)。可以讓子類有能力對(duì)算法的不同點(diǎn)進(jìn)行掛鉤。子類可以自行決定要不要覆蓋鉤子方法,如果不覆蓋,抽象類會(huì)提供一個(gè)默認(rèn)的實(shí)現(xiàn)。

    創(chuàng)建模版方法時(shí),什么時(shí)候使用抽象方法,什么時(shí)候使用鉤子?

    • 當(dāng)子類必須提供算法中某個(gè)方法或步驟的實(shí)現(xiàn)時(shí),就用抽象方法;
    • 如果算法的這個(gè)部分時(shí)可選的,就用鉤子。

    原則七:好萊塢原則,別調(diào)用(打電話給)我們,我們會(huì)調(diào)用(打電話給)你。

    允許低層組件將自己掛鉤到系統(tǒng)上,但高層組件會(huì)決定什么時(shí)候和這樣使用這些低層組件。
    好萊塢原則和模板方法

    好萊塢原則和依賴倒置原則的關(guān)系:

    • 依賴倒置原則教我們盡量避免使用具體類,而多使用抽象,更注重在設(shè)計(jì)中避免依賴。
    • 好萊塢原則是在創(chuàng)建框架或組件上的一種技巧,好讓低層組件能被掛鉤進(jìn)計(jì)算中,而不會(huì)讓高層組件依賴低層組件。
      工廠方法是模板方法的特例

    迭代器模式:提供一種方法順序訪問一個(gè)聚合對(duì)象中的各個(gè)元素,而又不暴露其內(nèi)部的表示。


    迭代器模式的餐廳菜單示例


    這個(gè)迭代器讓女招待員從具體類的實(shí)現(xiàn)中解耦,她不需要知道菜單是使用數(shù)組還是ArrayList,只關(guān)心她能夠取得迭代器。

    原則八:單一責(zé)任(基本原則):一個(gè)類應(yīng)該只有一個(gè)引起變化的原因。

    組合模式:允許你將對(duì)象組合成樹形結(jié)構(gòu)來表現(xiàn)“整體/部分”層次結(jié)構(gòu)。組合能讓客戶以一致的方式處理個(gè)別對(duì)象以及對(duì)象組合。


    組合模式類圖

    組合菜單

    狀態(tài)模式:允許對(duì)象在內(nèi)部狀態(tài)改變時(shí)改變它的行為,對(duì)象看起來好像修改了它的類。


    狀態(tài)模式的類圖幾乎跟策略模式的類圖一樣,但兩個(gè)模式的差別在于它們的意圖
    狀態(tài)模式將一群行為封裝在狀態(tài)對(duì)象中,context的行為隨時(shí)可委托到那些狀態(tài)對(duì)象中的一個(gè)。
    策略模式中客戶通常主動(dòng)指定context所要組合的策略對(duì)象是哪個(gè)。
    狀態(tài)模式糖果機(jī)具體狀態(tài)類示例

    糖果機(jī)類(Context)

    當(dāng)狀態(tài)轉(zhuǎn)換是固定的時(shí)候,狀態(tài)決定適合放在Context中,當(dāng)轉(zhuǎn)換是動(dòng)態(tài)時(shí),狀態(tài)決定就放在狀態(tài)類中。

    代理模式:為另一個(gè)對(duì)象提供一個(gè)替身或占位符以控制對(duì)這個(gè)對(duì)象的訪問。

    Java RMI: RMI提供客戶輔助對(duì)象和服務(wù)輔助對(duì)象,為客戶輔助對(duì)象創(chuàng)建和服務(wù)對(duì)象相同的方法,好處是客戶不必親自寫任何網(wǎng)絡(luò)或I/O代碼。
    RMI將客戶輔助對(duì)象成為stub(樁) ,服務(wù)輔助對(duì)象成為skeleton(骨架)

    制作遠(yuǎn)程服務(wù)的五個(gè)步驟:



    客戶如何取stub對(duì)象

    代理模式糖果機(jī)示例


    虛擬代理

    顯示CD封面示例
    創(chuàng)建一個(gè)Icon接口從網(wǎng)絡(luò)上加載圖像,在加載未完成時(shí)顯示“CD封面加載中,請(qǐng)稍后…”,一旦加載完成,代理就把顯示的職責(zé)委托給Icon。

    總結(jié)

    以上是生活随笔為你收集整理的笔记:Head First设计原则和设计模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。