14談?wù)勀阒赖脑O(shè)計(jì)模式_第1頁(yè)
14談?wù)勀阒赖脑O(shè)計(jì)模式_第2頁(yè)
14談?wù)勀阒赖脑O(shè)計(jì)模式_第3頁(yè)
14談?wù)勀阒赖脑O(shè)計(jì)模式_第4頁(yè)
14談?wù)勀阒赖脑O(shè)計(jì)模式_第5頁(yè)
已閱讀5頁(yè),還剩2頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、極客時(shí)間第14講 | 談?wù)勀阒赖脑O(shè)計(jì)模式?2018-06-05第14講 | 談?wù)勀阒赖脑O(shè)計(jì)模式?- 00:00 / 08:23設(shè)計(jì)模式是人們?yōu)?開(kāi)發(fā)中相同表征的問(wèn)題,抽象出的可重復(fù)利用的解決方案。在某種程度上,設(shè)計(jì)模式已經(jīng)代表了一些特定情況的最佳實(shí)踐,同時(shí)也起到了 工程師之間的“行話”的作用。理解和掌握典型的設(shè)計(jì)模式,有利于我們提高設(shè)計(jì)的效率和質(zhì)量。我要問(wèn)你的問(wèn)題是,談?wù)勀阒赖脑O(shè)計(jì)模式?請(qǐng)手動(dòng)實(shí)現(xiàn)單例模式,Spring等框架中使用了哪些模式?典型回答大致按照模式的應(yīng)用目標(biāo) ,設(shè)計(jì)模式可以分為創(chuàng)建型模式 結(jié)構(gòu)型模為型模式。創(chuàng)建型模式,是對(duì)對(duì)象創(chuàng)建過(guò)程的各種問(wèn)題和解決方案的總結(jié), 各種工廠模

2、式(Factory Abstract Factory) 單例模式(Singleton) 構(gòu)建器模式(Builder) 原型模式(ProtoType )。結(jié)構(gòu)型模式,是(Decorator)設(shè)計(jì)結(jié)構(gòu)的總結(jié),關(guān)注于類 對(duì)象繼承 組合方式的實(shí)踐經(jīng)驗(yàn)。常見(jiàn)的結(jié)構(gòu)型模式, 橋接模式(Bridge) 適配器模式(Adapter) 裝飾者模式模式(Proxy) 組合模式(Composite) 外觀模式(Facade)模式(Flyweight)等。行為型模式,是從類或?qū)ο笾g交互 職責(zé)劃分等角度總結(jié)的模式。比較常見(jiàn)的行為型模式有策略模式(Strategy) 解釋器模式(Interpreter) 命令模式(d)

3、觀察者模式(Observer) 迭代器模式(Iterator) 模板 模式(Template Method )考點(diǎn)分析這個(gè)問(wèn)題主要是考察你對(duì)設(shè)計(jì)模式的了解和掌握程度, 相關(guān)內(nèi)容你可以參考:者模式(Visitor)。 Patterns。我建議可以在回答時(shí)適當(dāng)?shù)嘏e些例子,更加清晰地說(shuō)明典型模式到底是什么樣子,典型使用場(chǎng)景是怎樣的。這里舉個(gè)Java基礎(chǔ)類庫(kù)中的例子供你參考。首先,專欄第11講剛過(guò)IO框架,我們知道InputStream是一個(gè)抽象類,標(biāo)準(zhǔn)類庫(kù)中提供了FileInputStream ByteArrayInputStream等各種不同的子類,分別從不同角度對(duì)InputStream進(jìn)行了功能

4、擴(kuò)展,這是典型的裝飾器模式應(yīng)用案例。識(shí)別裝飾器模式,可以通過(guò)識(shí)別類設(shè)計(jì)特征來(lái)進(jìn)行 ,也就是其類構(gòu)造函數(shù)以相同的抽象類或者接口為輸入?yún)?shù)。因?yàn)檠b飾器模式本質(zhì)上是包裝同類型實(shí)例,我們對(duì)目標(biāo)對(duì)象的調(diào)用,往往會(huì)通過(guò)包裝類覆蓋過(guò)的 ,迂回調(diào)用被包裝的實(shí)例,這就可以很自然地實(shí)現(xiàn)增加額外邏輯的目的,也就是所謂的“裝飾”。例如,BuferedInputStream經(jīng)過(guò)包裝,為輸入流過(guò)程增加緩存,類似這種裝飾器還可以多次嵌套,不斷地增加不同層次的功能。我在下面的類 ,簡(jiǎn)單總結(jié)了InputStream的裝飾模式實(shí)踐。public BuferedInputStream(InputStream in)極客時(shí)間接下來(lái)再

5、看第二個(gè)例子。創(chuàng)建型模式尤其是工廠模式,在我們的代碼中隨處可見(jiàn),我舉個(gè)相對(duì)不同的API設(shè)計(jì)實(shí)踐。比如,JDK最新版本中 HTTP/2API,下面這個(gè)創(chuàng)建HttpRequest的過(guò)程,就是典型的構(gòu)建器模式(Builder),通常會(huì)被實(shí)現(xiàn)成fuent風(fēng)格的API,也有人叫它鏈。使用構(gòu)建器模式,可以比較優(yōu)雅地解決構(gòu)建復(fù)雜對(duì)象的麻煩,這里的“復(fù)雜”是指類似需要輸入的參數(shù)組合較多,如果用構(gòu)造函數(shù),我們往往需要為每一種可能的輸入?yún)?shù)組合實(shí)現(xiàn)相應(yīng)的構(gòu)造函數(shù),一系列復(fù)雜的構(gòu)造函數(shù)會(huì)讓代碼閱讀性和可維護(hù)性變得很差。上面的分析也進(jìn)一步反映了創(chuàng)建型模式的初衷,即,將對(duì)象創(chuàng)建過(guò)程單獨(dú)抽象出來(lái),從結(jié)構(gòu)上把對(duì)象使用邏輯和

6、創(chuàng)建邏輯相互 ,隱藏對(duì)象實(shí)例的細(xì)節(jié),進(jìn)而為使用者實(shí)現(xiàn)了更加規(guī)范 統(tǒng)一的邏輯。更進(jìn)一步進(jìn)行設(shè)計(jì)模式考察,面試官可能會(huì):希望你寫(xiě)一個(gè)典型的設(shè)計(jì)模式實(shí)現(xiàn)。這雖然看似簡(jiǎn)單,但即使是最簡(jiǎn)單的單例,也能夠綜合考察代碼基本功??疾斓湫偷脑O(shè)計(jì)模式使用,尤其是結(jié)合標(biāo)準(zhǔn)庫(kù)或者主流開(kāi)源框架,考察你對(duì)業(yè)界良好實(shí)踐的掌握程度。在面試時(shí)如果恰好問(wèn)到你不熟悉的模式,你可以稍微引導(dǎo)一下,比如 你在 中使用了什么 相對(duì)熟悉的模式,試圖解決什么問(wèn)題,它們的優(yōu)點(diǎn)和缺點(diǎn)等。下面,我會(huì) 前面兩點(diǎn),結(jié)合代碼實(shí)例進(jìn)行分析。知識(shí)擴(kuò)展我們來(lái)實(shí)現(xiàn)一個(gè)日常非常熟悉的單例設(shè)計(jì)模式。看起來(lái)似乎很簡(jiǎn)單,那么下面這個(gè)樣例符合基本需求嗎?是不是總感覺(jué)缺了點(diǎn)

7、什么?原來(lái),Java會(huì)自動(dòng)為沒(méi)有明確 構(gòu)造函數(shù)的類,定義一個(gè)public的無(wú)參數(shù)的構(gòu)造函數(shù),所以上面的例子并不能保證額外的對(duì)象不被創(chuàng)建出來(lái),別人完全可以直接“new Singleton()”,那我們應(yīng)該怎么處理呢?不錯(cuò),可以為單例定義一個(gè)private的構(gòu)造函數(shù)(也有建議 為枚舉,這是有爭(zhēng)議的,我個(gè)人不建議選擇相對(duì)復(fù)雜的枚舉,畢竟日常開(kāi)發(fā)不是學(xué)術(shù)研究)。這樣還有什么改進(jìn)的余地嗎?專欄第10講ConcurrentHashMap時(shí),提到過(guò)標(biāo)準(zhǔn)類庫(kù)中很多地方使用懶加載(lazy-load), 初始內(nèi)存開(kāi)銷,單例同樣適用,下面是 后的改進(jìn)版本。這個(gè)實(shí)現(xiàn)在單線程環(huán)境不 問(wèn)題,但是如果處于并發(fā)場(chǎng)景,就需要

8、考慮線程安全,最熟悉的就莫過(guò)于“ 這里的volatile能夠提供可見(jiàn)性,以及保證getInstance返回的是初始化完全的對(duì)象。在同步之前進(jìn)行null檢查,以盡量避免進(jìn)入相對(duì)昂貴的同步塊?!保湟c(diǎn)在于:public class Singleton private satic Singleton insance; private Singleton() public satic Singleton getInsance() if (insance = null) insance = new Singleton();return insance;public class Singleton pr

9、ivate satic Singleton insance = new Singleton(); public satic Singleton getInsance() return insance;HttpReques reques = HttpReques.newBuilder(new URI(uri).header(header , valueAl ce).headers(headerBob, value1Bob, headerCarl, valueCarl, headerBob, value2Bob).GET().build();極客時(shí)間直接在class級(jí)別進(jìn)行同步,保證線程安全的類

10、調(diào)用。在這段代碼中,爭(zhēng)論較多的是volatile修飾靜態(tài)變量,當(dāng)Singleton類本身有多個(gè)成員變量時(shí),需要保證初始化過(guò)程完成后,才能被get到。在現(xiàn)代Java中,內(nèi)存排序模型(JMM)已經(jīng)非常完善,通過(guò)volatile的write或者,能保證所謂的happen-before,也就是避免常被提到的指令重排。換句話說(shuō),構(gòu)造對(duì)象的store指令能夠被定在volatile之前。當(dāng)然,也有一些人推薦利用內(nèi)部類持有靜態(tài)對(duì)象的方式實(shí)現(xiàn),其理論依據(jù)是對(duì)象初始化過(guò)程中隱含的初始化鎖(有 的話你可以參考jls-12.4 2 中對(duì)LC的說(shuō)明),這種和前面的雙檢鎖實(shí)現(xiàn)都能保證線程安全,不過(guò)語(yǔ)法稍顯晦澀,未必有特別

11、的優(yōu)勢(shì)。所以,可以看出,即使是看似最簡(jiǎn)單的單例模式,在增加各種高標(biāo)準(zhǔn)需求之后,同樣需要非常多的實(shí)現(xiàn)考量。上面是比較學(xué)究的考察,其實(shí)實(shí)踐中未必需要如此復(fù)雜,如果我們看Java 類庫(kù) 的單例實(shí)現(xiàn),比如java lang.Runtime,你會(huì)發(fā)現(xiàn):它并沒(méi)使用復(fù)雜的之類。靜態(tài)實(shí)例被為fnal,這是被通常實(shí)踐忽略的,一定程度保證了實(shí)例不被篡改(專欄第6講過(guò),反射之類可以繞過(guò)私有 限制),也有有限的保證執(zhí)行順序的語(yǔ)義。前面說(shuō)了不少代碼實(shí)踐,下面一起來(lái)簡(jiǎn)要看看主流開(kāi)源框架,如Spring等如何在API設(shè)計(jì)中使用設(shè)計(jì)模式。你至少要有個(gè)大體的印象,如:BeanFactory和ApplicationContext

12、應(yīng)用了工廠模式。在Bean的創(chuàng)建中,Spring也為不同scope定義的對(duì)象,提供了單例和原型等模式實(shí)現(xiàn)。我在專欄第6講的AOP領(lǐng)域則是使用了 模式 裝飾器模式 適配器模式等。各種器,是觀察者模式的典型應(yīng)用。類似Template 等則是應(yīng)用了模板模式。,我與你回顧了設(shè)計(jì)模式的 和主要類型,并從Java 類庫(kù) 開(kāi)源框架等不同角度分析了其采用的模式,并結(jié)合單例的不同實(shí)現(xiàn),分析了如何實(shí)現(xiàn)符合線程安全等需求的單例,希望可以對(duì)你的工程實(shí)踐有所幫助。另外, 最后補(bǔ)充的是,設(shè)計(jì)模式也不是銀彈,要避免 或者過(guò)度設(shè)計(jì)。一課一練關(guān)于設(shè)計(jì)模式你做到心中有數(shù)了嗎?你可以思考下,在業(yè)務(wù)代碼中,經(jīng)常發(fā)現(xiàn)大量XXFacad

13、e,外觀模式是解決什么問(wèn)題?適用于什么場(chǎng)景?請(qǐng)你在留言區(qū)寫(xiě)寫(xiě)你對(duì)這個(gè)問(wèn)題的思考,我會(huì)選出經(jīng)過(guò)認(rèn)真思考的留言,送給你一份學(xué)習(xí)鼓勵(lì)金,歡迎你與我一起討論。你的朋友是不是也在準(zhǔn)備面試呢?你可以“請(qǐng)朋友讀”,把 的題目 給好友,或許你能幫到他。private satic fnal Runtime currentRuntime = new Runtime(); private satic Version version;/ public satic Runtime getRuntime() return currentRuntime;/* Don't let anyone else ins at

14、e this class */ private Runtime() public class Singleton private Singleton()public satic Singleton getSingleton() return Holder.singleton;private satic class Holder private satic Singleton singleton = new S ngleton();public class Singleton private satic volatile Singleton singleton = null; private S

15、ingleton() public satic Singleton getSingleton() if (singleton = null) / 盡量避免重復(fù)進(jìn)入同步塊synchronized (Singleton.class) / 同步.class 意味著對(duì)同步類 調(diào)用if (singleton = null) singleton = new Singleton();return singleton;極客時(shí)間sunlight0012018-06-05fascade是門(mén)面模式 為復(fù)雜的邏輯提供簡(jiǎn)單的借口 設(shè)計(jì)模式學(xué)的時(shí)候還能明白 但是用的結(jié)合流行的開(kāi)源框架 或者 的項(xiàng)目學(xué)設(shè)計(jì)模式是很 辦法 生

16、學(xué)很容易看不懂學(xué)不下去時(shí)候就不知道該怎么用了 我們?cè)趺丛陧?xiàng)目中使用設(shè)計(jì)模式呢?作者回復(fù)2018-06-06不必為了模式而用 優(yōu)先解決開(kāi)發(fā)、維護(hù)中的痛點(diǎn)公號(hào)-Java大后端2018-06-05之前放置了一個(gè)新的 對(duì)象 只能通過(guò)該對(duì)象才能使用該系統(tǒng) 不再 其它方式 該系統(tǒng) 該 對(duì)象封裝了 原系統(tǒng)的所有規(guī)則和接口提供門(mén)面模式形象上來(lái)講就是的API接口較之使用原系統(tǒng)會(huì)更加的簡(jiǎn)單舉例:JUnitCore是JUnit類的 Facade模式的實(shí)現(xiàn)類 外部使用該 對(duì)象與JUnit進(jìn)行統(tǒng)一交互 驅(qū)動(dòng)執(zhí) 試代碼使用場(chǎng)景:當(dāng)我們希望封裝或隱當(dāng)我們使用原系統(tǒng)的功能并希望增加一些新的功能 編寫(xiě)新類的成本遠(yuǎn)小于所有人學(xué)會(huì)

17、使用或者未來(lái)維護(hù)原系統(tǒng)所需的成本缺點(diǎn): 了開(kāi)閉原則擴(kuò)展 只能直接修改 對(duì)象作者回復(fù)2018-06-06不錯(cuò)文TSOS2018-06-05為什么我去查Runtime的源碼 currentRuntime沒(méi)有被fnal修飾呢?作者回復(fù)2018-06-06什么版本?我這是最新的云學(xué)2018-06-09最開(kāi)始迷戀設(shè)計(jì)模式 后來(lái)眼中沒(méi)有模式 其實(shí) 經(jīng)典的設(shè)計(jì)模式的書(shū)的第一章就非常明確的指出設(shè)計(jì)模式不是銀彈 總感覺(jué)java語(yǔ)言寫(xiě)的c+更重 很多代碼都是無(wú)用的裝飾李志博2018-06-05Spring 內(nèi)部的asm 模塊 用到了 者模式Sin02018-06-05有一點(diǎn)理解不太一致 單例模式double ch

18、eck中synchronized就已經(jīng)可以提供可見(jiàn)性 volatile的作用主要體現(xiàn)在禁指令重排!作者回復(fù)2018-06-06不sync也不是必然走到潤(rùn)茲2018-06-05在沒(méi)用facade之前 為了完成某個(gè)功能需要調(diào)用的各 進(jìn)行組合才能完成 用了facade之后相當(dāng)于把多個(gè) 調(diào)用聚 了一個(gè)方便用戶調(diào)用2018-06-06公司項(xiàng)目是一個(gè)基于s boot、mybatis開(kāi)發(fā)的web后端管理項(xiàng)目 現(xiàn)在的問(wèn)題是 不同角色登錄到系統(tǒng)看到的模塊和模塊里面的數(shù)據(jù)是不一樣的 有時(shí)雖然看到的模塊一樣 但是由于角色不一樣 所以顯示的數(shù)據(jù)是不一樣 在這樣的情況下 會(huì)經(jīng)常在service層 里面 角色然后改變ma

19、pper的數(shù)據(jù)操作條件或調(diào)用mapper的不同由于在service層頻繁的 角色感覺(jué)很不雅 新增角色就要加哎 感覺(jué)可以用策略設(shè)計(jì)模式不知道怎么具體設(shè)計(jì)星空2018-06-05外觀模式為子系統(tǒng)中一組接口提供一個(gè)統(tǒng)一 的接口 降低了客戶端與子系統(tǒng)之間的耦合 簡(jiǎn)化了系統(tǒng)復(fù)雜度 缺點(diǎn)是 了開(kāi)閉原則 適用于為一系列復(fù)雜的子系統(tǒng)提供一個(gè)友好簡(jiǎn)單的入口 將子系統(tǒng)與客戶端解偶 公司基礎(chǔ)paas平臺(tái)用到了外觀模式 具體是定義一個(gè)ServiceFacade 然后通過(guò)繼承眾多xxService,對(duì)外提供子xxService的服務(wù)作者回復(fù)2018-06-06業(yè)務(wù)開(kāi)發(fā)很普遍2018-07-11極客時(shí)間我有個(gè)疑問(wèn) 單例那

20、里可否不用volatile 初始化時(shí)Singleton temp=new Singleton();this.singleton=temp;這樣能保證初始化完成才賦值嗎?Miaozhe2018-06-08提供統(tǒng)一的服務(wù) 就是 外部系統(tǒng)對(duì)內(nèi)部服務(wù)的具體實(shí)現(xiàn) 以及各微服務(wù)的部署虛擬機(jī)和URL我理解Facada模式 微服務(wù)應(yīng)用場(chǎng)景 如 Nginx對(duì)系統(tǒng)子服務(wù)進(jìn)行管理和IP反向再者 容器Docker技術(shù) 我認(rèn)為這是Facada模式 通過(guò)鏡像把應(yīng)用相關(guān)的組件和配置都預(yù)置好 發(fā)布這個(gè)服務(wù)時(shí) 直接啟動(dòng)容器 用戶不用關(guān)心里面的任何細(xì)節(jié)楊 看看 我分析的對(duì)嗎?Walter2018-06-07外觀模式(Facade

21、 Pattern)隱的復(fù)雜性 并向客戶端提供了一個(gè)客戶端可以 系統(tǒng)的接口 它向現(xiàn)有的系統(tǒng)添加一個(gè)接口 來(lái)隱的復(fù)雜性這種模式涉及到一個(gè)單一的類 該類提供了客戶端請(qǐng)求的簡(jiǎn)化 和對(duì)現(xiàn)有系統(tǒng)類 的委托調(diào)用意圖 為子系統(tǒng)中的一組接口提供一個(gè)一致的界面 外觀模式定義了一個(gè) 接口 這個(gè)接口使得這一子系統(tǒng)更加容易使用主要解決 降低 復(fù)雜系統(tǒng)的時(shí)的復(fù)雜度 簡(jiǎn)化客戶端與之的接口何時(shí)使用 1、客戶端不需要知道系統(tǒng)內(nèi)部的復(fù)雜整個(gè)系統(tǒng)只需提供一個(gè)"接待員"即可 2、定義系統(tǒng)的如何解決 客戶端不耦合 外觀類耦合關(guān)鍵代碼 在客戶端和復(fù)雜系統(tǒng)之間再加一層 這一層將調(diào)用順序、依賴 等處理好應(yīng)用實(shí)例 1、去醫(yī)院看病 可能要去掛號(hào)、門(mén)診、劃價(jià)、取藥 讓患者或患者家屬覺(jué)得很復(fù)雜 如果有提供接待只讓接待 來(lái)處理 就很方便 2、JAVA 的三層開(kāi)發(fā)模式優(yōu)點(diǎn) 1、減少系統(tǒng)相互依賴 2、提高靈活性 3、提高了安全性缺點(diǎn) 不符合開(kāi)閉原則 如果要改東西很麻煩 繼承重寫(xiě)都不合適使用場(chǎng)景 1、為復(fù)雜的模塊或子系統(tǒng)提供外界 的模塊 2、子系統(tǒng)相對(duì)注意事項(xiàng) 在層次化結(jié)構(gòu)中 可以使用外觀模式定義系統(tǒng)中每一層的3、預(yù)防低水平 帶來(lái)的風(fēng)險(xiǎn)作者回復(fù)2018-06-07不錯(cuò) 業(yè)務(wù)系統(tǒng)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論