1. 如何判斷你已經(jīng)掌握了某種設(shè)計(jì)模式客冈?(非常重要)
- ① 這個(gè)模式的意圖是什么?它解決了什么問(wèn)題、什么時(shí)候可以使用它
- ② 它是如何解決的惠啄?掌握它的結(jié)構(gòu)圖,記住它的關(guān)鍵代碼
- ③ 至少能夠想到它的兩個(gè)應(yīng)用實(shí)例任内,一個(gè)生活中的撵渡,一個(gè)軟件中的
- ④ 這個(gè)模式的缺點(diǎn)是什么?在使用時(shí)要注意什么
一死嗦、單例模式
1. 這個(gè)模式的意圖是什么趋距?它解決了什么問(wèn)題、什么時(shí)候使用它
- 什么時(shí)候使用它:
- ① 系統(tǒng)只需要一個(gè)實(shí)例對(duì)象越除,如系統(tǒng)要求提供一個(gè)唯一的序列號(hào)生成器或資源管理器节腐,或者需要考慮資源消耗太大而只允許創(chuàng)建一個(gè)對(duì)象。
- ② 客戶調(diào)用類的單個(gè)實(shí)例只允許使用一個(gè)公共訪問(wèn)點(diǎn)摘盆,除了該公共訪問(wèn)點(diǎn)翼雀,不能通過(guò)其他途徑訪問(wèn)該實(shí)例。
2. 它是如何解決的孩擂?掌握它的結(jié)構(gòu)圖狼渊,記住它的關(guān)鍵代碼
- 關(guān)鍵代碼:
class TaskManager
{
private static TaskManager tm = null;
private TaskManager() {……} //初始化窗口
public void displayProcesses() {……} //顯示進(jìn)程
public void displayServices() {……} //顯示服務(wù)
public static TaskManager getInstance()
{
if (tm == null)
{
tm = new TaskManager();
}
return tm;
}
……
}
3. 至少能夠想到它的兩個(gè)應(yīng)用實(shí)例,一個(gè)軟件中的类垦,一個(gè)生活中的
- 軟件中:實(shí)現(xiàn)一臺(tái)負(fù)載均衡的流量入口服務(wù)器
- 生活中:電腦中的任務(wù)管理器
4. 這個(gè)模式的缺點(diǎn)是什么狈邑?在使用時(shí)要注意什么
- ① 由于單例模式中沒(méi)有抽象層,因此單例類的擴(kuò)展很大的困難蚤认。
- ② 單例類的職責(zé)過(guò)重官地,在一定程度上違背了
單一職責(zé)原則
。因?yàn)閱卫惣瘸洚?dāng)了工廠角色烙懦,提供了工廠方法驱入,同時(shí)又充當(dāng)了產(chǎn)品角色,包含一些業(yè)務(wù)方法氯析,將產(chǎn)品的創(chuàng)建和產(chǎn)品的本身的功能融合到一起亏较。 - ③ 現(xiàn)在很多面向?qū)ο笳Z(yǔ)言(如Java、C#)的運(yùn)行環(huán)境都提供了自動(dòng)垃圾回收的技術(shù)掩缓,因此雪情,如果實(shí)例化的共享對(duì)象長(zhǎng)時(shí)間不被利用,系統(tǒng)會(huì)認(rèn)為它是垃圾你辣,會(huì)自動(dòng)銷毀并回收資源巡通,下次利用時(shí)又將重新實(shí)例化尘执,這將導(dǎo)致共享的單例對(duì)象狀態(tài)的丟失。
二宴凉、適配器模式
1. 這個(gè)設(shè)計(jì)模式的意圖是什么誊锭?它解決了什么問(wèn)題、什么時(shí)候可以使用它
- 什么時(shí)候使用它:
- 將一個(gè)接口轉(zhuǎn)換成客戶希望的另一個(gè)接口弥锄,使接口不兼容的那些類可以一起工作丧靡。
-
通俗來(lái)講:
讓兩個(gè)無(wú)法相互調(diào)用的類,在不修改它們代碼的情況下籽暇,增加一個(gè)適配器來(lái)讓它們能工作起來(lái)温治。
2. 它是如何解決的?掌握它的結(jié)構(gòu)圖戒悠,記住它的關(guān)鍵代碼
結(jié)構(gòu)圖:
Target(目標(biāo)抽象類):
目標(biāo)抽象類定義客戶所需接口熬荆,可以是一個(gè)抽象類或接口,也可以是具體類绸狐。Adapter(適配器類):
適配器可以調(diào)用一個(gè)接口卤恳,作為一個(gè)轉(zhuǎn)換器,對(duì) Adaptee 和 Target 進(jìn)行適配六孵,適配器是適配器模式的核心,在對(duì)象適配器中幅骄,它通過(guò)繼承 Target 并關(guān)聯(lián)一個(gè) Adaptee 對(duì)象使得二者產(chǎn)生聯(lián)系劫窒。Adaptee(適配者類):
適配者即被適配的角色,它定義了一個(gè)已經(jīng)存在的接口拆座,這個(gè)接口需要適配主巍,適配者類一般是一個(gè)工具類,包含了客戶希望使用的業(yè)務(wù)方法挪凑,在某些情況下可能沒(méi)有適配者的源代碼孕索。關(guān)鍵代碼:
class Adapter extends Target {
private Adaptee adaptee; //維持一個(gè)對(duì)適配者對(duì)象的引用
public Adapter(Adaptee adaptee) {
this.adaptee=adaptee;
}
public void request() {
adaptee.specificRequest(); //轉(zhuǎn)發(fā)調(diào)用
}
}
3. 至少能夠想到它的兩個(gè)應(yīng)用實(shí)例,一個(gè)軟件中的躏碳,一個(gè)生活中的
- 軟件中:比如一個(gè) APP 承接了多個(gè)廣告商搞旭,為了統(tǒng)一調(diào)用這些廣告(適配者),就可以提供一個(gè)適配器類菇绵,這樣客戶就能方便的獲取廣告肄渗。
- 生活中:筆記本電腦的
電源適配器
,就把國(guó)際統(tǒng)一標(biāo)準(zhǔn)的 220v 電壓咬最,轉(zhuǎn)換成 40v翎嫡,供給電腦使用
4. 這個(gè)模式的缺點(diǎn)是什么?在使用時(shí)要注意什么
- 沒(méi)啥缺點(diǎn)
三永乌、組合模式
1. 這個(gè)設(shè)計(jì)模式的意圖是什么惑申?它解決了什么問(wèn)題具伍、什么時(shí)候可以使用它
- 解決了什么問(wèn)題:
-
組合模式
為處理樹形結(jié)構(gòu)
提供了一種較為完美的解決方案,它描述了如何將容器和葉子進(jìn)行遞歸組合圈驼,使得用戶在使用時(shí)無(wú)須對(duì)它們進(jìn)行區(qū)分人芽,可以一致地對(duì)待容器和葉子。
2. 它是如何解決的碗脊?掌握它的結(jié)構(gòu)圖啼肩,記住它的關(guān)鍵代碼
- 結(jié)構(gòu)圖:
-
Component(抽象構(gòu)件):
它可以是接口或者抽象類,為葉子構(gòu)件和容易構(gòu)件對(duì)象聲明了接口衙伶,在該角色中可以保護(hù)所有子類共有行為的聲明和實(shí)現(xiàn)祈坠。 -
Leaf(葉子構(gòu)件):
它在組合結(jié)構(gòu)中表示葉子節(jié)點(diǎn)對(duì)象,葉子節(jié)點(diǎn)沒(méi)有子節(jié)點(diǎn)矢劲,它實(shí)現(xiàn)了抽象構(gòu)件中定義的行為赦拘。 -
Composite(容器構(gòu)件):
它在組合結(jié)構(gòu)中表示容器節(jié)點(diǎn)對(duì)象,容器節(jié)點(diǎn)保護(hù)子節(jié)點(diǎn)芬沉,其子節(jié)點(diǎn)可以是葉子節(jié)點(diǎn)躺同,也可以是容器節(jié)點(diǎn)。
核心思想:
組合模式的關(guān)鍵是定義了一個(gè)抽象構(gòu)件類丸逸,它既可以表示葉子蹋艺,又可以代表容器,而客戶端針對(duì)該抽象構(gòu)件進(jìn)行編程黄刚,無(wú)須知道它到底表示的是葉子節(jié)點(diǎn)還是容器捎谨,可以對(duì)其進(jìn)行統(tǒng)一處理。
關(guān)鍵代碼:
abstract class Component {
public abstract void add(Component c); //增加成員
public abstract void remove(Component c); //刪除成員
public abstract Component getChild(int i); //獲取成員
public abstract void operation(); //業(yè)務(wù)方法
}
class Leaf extends Component {
public void add(Component c) {
//異常處理或錯(cuò)誤提示
}
public void remove(Component c) {
//異常處理或錯(cuò)誤提示
}
public Component getChild(int i) {
//異常處理或錯(cuò)誤提示
return null;
}
public void operation() {
//葉子構(gòu)件具體業(yè)務(wù)方法的實(shí)現(xiàn)
}
}
class Composite extends Component {
private ArrayList<Component> list = new ArrayList<Component>();
public void add(Component c) {
list.add(c);
}
public void remove(Component c) {
list.remove(c);
}
public Component getChild(int i) {
return (Component)list.get(i);
}
public void operation() {
//容器構(gòu)件具體業(yè)務(wù)方法的實(shí)現(xiàn)
//遞歸調(diào)用成員構(gòu)件的業(yè)務(wù)方法
for(Object obj:list) {
((Component)obj).operation();
}
}
}
3. 至少能夠想到它的兩個(gè)應(yīng)用實(shí)例憔维,一個(gè)生活中的涛救,一個(gè)軟件中的
- 軟件中:設(shè)計(jì)文件夾和文件系統(tǒng)
- 生活中:公司的組織機(jī)構(gòu)設(shè)計(jì)
4. 這個(gè)模式的缺點(diǎn)是什么?在使用時(shí)要注意什么
- 在新增構(gòu)件時(shí)很難對(duì)容器中的構(gòu)件類型進(jìn)行限制业扒。有時(shí)候我們希望一個(gè)容器中只能有某些特點(diǎn)類型的對(duì)象检吆,例如在某個(gè)文件夾中只能包含文本文件,使用組合模式時(shí)程储,不能依賴類型系統(tǒng)來(lái)施加這些約束蹭沛,因?yàn)樗鼈兌紒?lái)自于相同的抽象層,在這種情況下章鲤,必須通過(guò)運(yùn)行時(shí)進(jìn)行類型檢查來(lái)實(shí)現(xiàn)致板,這個(gè)實(shí)現(xiàn)過(guò)程較為復(fù)雜。