GoF:html
必背java
24種設計模式 :mysql
3個者 ,3個兩字的,2個器,2個三字的,1個四字的程序員
六大規則 :正則表達式
其餘介紹redis
其餘隨筆:算法
若是想成爲一名更優秀的軟件設計師,瞭解軟件設計的演變過程比學習優秀設計自己更有價值,由於設計的演變過程當中蘊含着大智慧。sql
理解:是否是說其實目前咱們所用到的優秀中間件,框架,MQ,Zookeeper,redis等想學習了深刻理解他們首選就要先知道爲何咱們選擇他,他解決了哪些痛點,難點?又是如何一步一步演化爲先現在的功能樣式的。在設計模式中,除了瞭解這個設計模式是什麼?還要了解爲何這樣設計纔是好的?如何想到這樣的設計的?數據庫
WHAT WHY HOW編程
P16 :UML圖的認識
面向對象的編程,並非類越多越好,類的劃分是爲了封裝,但分類的基礎是抽象,具備相同屬性和功能的對象的抽象集合纔是類。
因此由於一點變化就建立一個類是不行的,得是一種對象的描述才行。如動物下分雞鴨魚,而不是一件商品打678折或者滿500減100這種狀況劃分類。
算法或者細節等如打折的改變通常喜歡用策略模式來封裝。策略模式就是用來封裝算法的,在實踐中,咱們能夠用它來封裝幾乎任何類型的規則,只要在分析過程當中聽到須要在不一樣時間應用不一樣的業務規則,就能夠考慮使用策略模式處理這種變化的可能性。
儘可能的讓客戶端或者調用者認識(或者說引用,建立均可以)最少的類或者說知識,其餘調用端沒必要認識或者知道的所有封裝起來,遵照最小知道原則。
高手和菜鳥的區別就是高手能夠花一樣的代價獲取最大的利益或者說作一樣的事花最小的代價。
單一職責原則:就一個類而言,應該僅有一個引發它變化的緣由。(由於他職責單一,因此只有份屬於他的職責功能變化了纔去改變他,其餘狀況下他是不變的。)
模板方法模式
模板方法模式:定義一個操做中的算法的骨架(流程),而將一些步驟延遲到子類中。模板方法使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定步驟。
大致是抽象類定義算法的股價,具體子類重定義相關細節的方法來實現具體的步驟。模板方法模式是經過把不變行爲搬移到超類,去除子類中的重複代碼來體現他的優點。是一個 很好的代碼服用平臺,能夠幫子類擺脫重複的不變行爲的糾纏。
例子:每一個考生的考試試卷及答案能夠提煉爲模板方法模式,即除了答案做爲抽象方法給每一個考生重寫實現,其餘不變的框架都在父類上定義。
大衆汽車的生產,流程都是同樣的,可是具體的細節如用的材料,車型,定位的不一樣而生產出不同的大衆汽車,高爾夫,途觀,帕薩特。
汽車玻璃的生產,不一樣的汽車有不一樣的擋風玻璃形狀,但生產擋風玻璃的流程和模型是同樣的,只是根據不一樣的汽車玻璃形狀來生產。
模板方法中,因此不變的都提高到父類中,再讓具體的變化用子類去重寫實現。
當咱們要完成在某一細節層次一致的一個過程或一系列步驟,但其個別不走在更詳細的層次上的實現可能不一樣時,一般選擇用模板方法模式來處理。
迪米特法則
也叫最小知道原則
沒有管理,單靠人際關係協調是很難辦成事兒的。由於三個和尚沒水喝,互相推諉。
定義:若是兩個類沒必要彼此直接通訊,那麼這兩個類就不該當發生直接的相互做用。若是其中一個類須要調用另一個類的某個方法的話,能夠經過第三者轉發這個調用。???第三者?(意思是我想要丈母孃作晚飯我不須要直接叫她,我能夠經過寶寶來轉發調用)
強調了類之間的鬆耦合,耦合越弱,越有利於複用,這樣當一個弱耦合的類被修改,不會對有關係的類形成波及。
外觀模式
體現依賴倒置和迪米特原則
定義:爲子系統中的一組接口提供一個一致的界面,此模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
即讓調用者調用一個統一的入口接口,這個接口整合了須要被調用類的功能,經過引用整合,向外提供方法服務。
例子:三層架構Controller》Service》Dao ,層與層之間創建外觀Facade,即都向上提供服務;浙江ocrm老系統屬於遺留大型系統,與其交互運用外觀模式,經過設計一個Facade類,來提供清晰簡單的接口,讓訂單中心與Facade對象交互,Facade對象與ocrm老系統交互複雜的工做;不是直接買股票而是經過基金來買股票,基金就是外觀對象;功能按鈕,一個功能裏面有多個功能組成。
俄羅斯方塊遊戲的邏輯本質:
遊戲區域能夠設計爲一個二維整形數據來表示座標,如寬10,高20.例子:
int [][] arraySquare = new int[10][20];
那麼整個方塊的移動其實就是數組的下標變化,而每一個數組的值就是是否存在方塊的標誌,存在爲1,不存在缺省爲0.
單一職責原則:
職責分離是由於若是一個類承擔的職責過多,就等於把這些類耦合在一塊兒,須要分離開,如找出哪些是界面,哪些是遊戲邏輯,進行分離。
開閉原則:
典型例子:一國兩制.
上班時間打卡制度:對工做時間或業績成效的修改關閉,對時間制度拓展的開發,如彈性工做、打卡時間波動8:30-9:30
軟件實體(類、模塊、函數等)應該能夠擴展,但不能修改。但這只是理想上的原則,要儘可能作到,則必須在設計時先猜想出最有可能發生的變化種類,而後構造抽象來隔離這些變化。
面對需求,對程序的改動是增長新代碼進行的,而不是更改現有的代碼。而這也就須要經過構造抽象來隔離,
如計算器構造運算類,加減乘除繼承該運算類;導出excel文件的導出基類,具體的導出文件繼承基類來豐富導出字段等。
面向對象的4大好處:可維護,可擴展,可複用,靈活性好。
PC電腦硬件的發展,和麪向對象思想的發展是相似的。(遵循6大準則)
程序中全部的依賴關係都是終止於抽象類或者接口,那就是面向對象的設計,反之就是過程化的設計了。
時間萬物都是遵循某種相似的規律,誰先把握了這些規律,誰就最先成爲了強者。
裝飾器模式
例子:人和衣服搭配;I/O流的裝飾器類;工廠的產品包裝,如糖果和外包裝,汽車和內飾配置。
建造者模式要求建造的過程必須是穩定的,與裝飾器模式的區別是裝飾器模式的建造過程是不穩定的,他能夠有很是多種搭配。
裝飾模式:動態地給一個對象添加一些額外的職責,就增長功能來講,裝飾模式比生成子類更爲靈活(裝飾模式也是要生成繼承於組件的子類,而後在該子類基礎上增長set該組件的功能,知足後面繼承該裝飾器類的子類能夠在不影響組件功能的狀況下增長額外功能。)
裝飾模式的使用特色:
裝飾模式是爲已有功能動態地添加更多功能的一種方式。避免在已有的主類上加入新的字段,方法等增長了主類的複雜度,且新加的額外功能只適用於知足一些特定狀況下才會執行的特殊行爲的須要。這時候若是用裝飾模式,把要裝飾的功能放在單獨的類中,讓這個類包裝他要裝飾的對象,則當須要執行特殊行爲或者說額外功能時,就能夠有選擇按順序地運行使用裝飾功能的包裝對象了。(優勢:有效地把類的核心職責和裝飾功能區分開)
代理模式
中間商
例子:簽證代理,開公司代理
代理模式中真實實體和代理類共用接口,即實現同一個接口,這其中代理類會保存一個真實實體的引用,在調用方調用接口方法時,代理類就能經過多態代替實體。
使用場合:
遠程代理 :?
虛擬代理: html網頁上的圖片框經過虛擬代理代替了真實的圖片,存儲了真是圖片的路徑和尺寸,這樣等加載好了就能替換過來,在這以前經過虛擬代理保持了網頁的格式和輪廓。
安全代理:用來控制真實對象訪問時的權限。
智能指引:指調用真實的對象時,代理處理另一些事,也就是除了代理的事還多作些其餘事。
工廠方法模式
gg
例子:大規模生產時,如富士康不一樣款的手機生產對應不一樣的流水線。
工廠方法模式是在簡單工廠模式的基礎上的抽象和擴張,即在簡單工廠模式上,把工廠抽象出來,讓要生產的具體產品分別有對應生產該產品具體的工廠類(繼承於抽象工廠,經過多態來實現),其優勢在於把簡單工廠的內部邏輯判斷(選擇生產什麼產品)轉移到了客戶端代碼上來。如今想要增長新的產品,原本是修改工程類,如今是修改客戶端調用,增長新的工廠,克服了簡單工廠違背的開發-封閉原則的缺點。
(PS:但仍是沒能避免修改客戶端的代碼,能夠經過簡單工廠模式加反射來避免工廠類中的分支判斷問題替代工廠方法。)
原型模式
複製
例子:打印機;簡歷複製;傳單;電影膠捲
原型模式:用原型實例指定建立對象的種類,並經過拷貝這些原型建立新的對象。
提供一個clone方法來進行原型對象複製。
clone有深複製和淺複製區分。
通常在初始化信息不發生變化的狀況下,克隆是最後的辦法。這既隱藏了對象建立的細節,又大大提升了性能(爲何這麼說?)。
建造者模式
定義:將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。
建築這模式的過程是穩定的,而具體建造的細節是不一樣的,使用建造者模式時,用戶只需指定須要建造的類型就能夠獲得它們,而具體建造的過程和細節就不須要知道了。
構建一個抽象的建造類,讓要實現的產品繼承這個建造類,實現裏面的抽象方法(建造細節)。
還要有個指揮者類(項目經理),用它來控制建造過程,也用它來隔離用戶與建造過程的關聯;即用戶把想要的產品建造類給我,具體怎麼組裝用戶想要的產品交給指揮者。
例子:建造人;肯德基麥當勞的炸雞生產是建造者模式,而不是靠廚師;建造房子。
建造者模式是在當建立複雜對象的算法(方法)應該獨立於該對象的組成部分以及他們的裝配方式時適用的模式。
那建造者模式和模板方法的區別?
A:模板方法模式是純粹給算法用的,用於算法架構與算法細節分離;而建造者模式是給算法和他的組成部分用的,用於算法和對象結合時用?
觀察者模式
觀察者模式,又叫發佈/訂閱模式
一對多關係用
通常是有個接口類主題或者叫抽象通知者(Subject),一個接口類觀察者(Observer)。具體的主題如微博關注的明星實現接口類主題,粉絲實現觀察者。
依賴倒置原則的最佳體現。
例子:idea啓動後啓動按鈕的變化,log窗口的顯示等就是依賴於觀察者模式;訂閱報紙;微博關注的人更新微博,粉絲就能收到。
定義:觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。當這些主題對象在狀態發送變化時,就會通知全部的觀察者對象,使他們可以自動更新本身,作本身受到變化通知後想調整的邏輯狀態。
當咱們將一個系統分割成一系列互相協做的類時會由於須要維護相關對象間的一致性(因一個主題變化而變化)而使得各種間緊密耦合,這樣會給維護、擴展、重用都帶來不便。這時候當一個對象的改變須要同時改變其餘對象且不清楚具體有多少對象須要改變時,最佳方法即是觀察者模式來,解除耦合。
而當須要變化的觀察者已經被封裝爲一個個控件,沒法實現觀察者接口時,咱們就須要經過事件委託(java中是監聽器)來實現觀察者模式。
抽象工廠模式
工廠方法模式適合少數幾個產品系列問題,當要解決涉及多個產品系列問題是,要用抽象工廠模式。
例子:數據庫訪問(有mysql,Oracle等不一樣的數據庫類型)
提供一個建立一系列(該抽象工廠裏面提供了建立一系列的產品的抽象方法,注意是一系列產品)相關或相互依賴對象的接口,而無需指定他們具體的類。抽象工廠和工廠方法的區別即是抽象工廠建立的產品是涉及多個的,而工廠方法不是。
能夠用簡單工廠模式替換抽象工廠模式,就是在簡單工廠里加判斷該實現哪一類對象switch...case模式。
並且咱們能夠在使用簡單工廠模式的地方考慮用反射技術來去除switch 或if ,解除分支判斷帶來的耦合,由於反射時能夠用變量來決定要運行時實例化的對象,這樣就能夠用傳入的變量來決定要實例化的分支。(注意:要學習下怎麼在簡單工廠上加反射)
勉勵
無癡迷,不成功 。一個程序員若是歷來沒有熬夜寫程序的經歷,就不能算是一個好程序員,由於他沒有癡迷過,因此他不會有大成就。確實,成就和投入的經歷和時間成正比。
狀態模式
遵循單一職責原則、開發關閉原則
面向對象設計其實就是但願作到代碼的責任分解。
使用時有個類包含了狀態抽象類引用(工做類),各類不一樣的子類狀態分別對應不一樣的行爲處理(不一樣工做狀態)
例子:上班狀態,不一樣的狀態不一樣的行爲效率。軍隊上不一樣號角表示的不一樣戰備警備狀態,對於不一樣的處理方式。
定義:當一個對象的內在狀態改變時容許改變其行爲,這個對象看起來像是改變了其類。
主要解決的是當控制一個對象狀態轉換的條件表達式過於複雜時,就把狀態的判斷邏輯轉移到表示不一樣狀態的一系列類當中,這樣把複雜的判斷邏輯簡化(到各個類中)。
這樣能夠將特定狀態相關的行爲局部化,並吧不一樣狀態的行爲分割開來,消除了龐大的條件分支語句。
當一個對象的行爲取決於它的狀態,而且它必須在運行時刻根據狀態改變他的行爲時,使用狀態模式。
適配器模式
例子:電源適配器(改變電壓使得符合國內220V標準);翻譯;可調節高度座椅。
在咱們不能改變調用對接接口的雙方的前提下,咱們能作的就是想辦法找個適配器。通常如兩個公司系統間的數據和行爲都正確,但接口不符時的對接。
定義:將一個類的接口轉換成客戶但願的另一個接口。適配器模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做。
簡單說就是須要的東西就在眼前,但卻不能使用,短期沒法改造它,因而想辦法適配是最好的選擇。
類適配器模式(須要經過多重繼承來對兩個接口進行匹配,不適合java等單繼承語言)和對象適配器模式(主要是這個)。
適配器模式中,經過用適配類繼承目標類,即客戶端想調用的類來實現適配。適配類內部包裝了被適配的私有對象,在調用方法中實際是經過私有對象調用想要的方法。適用於雙方都不太容易修改的時候再使用適配器模式適配。
適配器模式主要用於軟件維護中因功能相似而接口不一樣時所用的無奈之舉,亡羊補牢,有點像扁鵲說本身的醫術。若是是在設計階段,應該考慮的不是適配,而是經過重構統一接口。
備忘錄模式
例子:遊戲進度保存;複製粘貼,網頁前進後退這種頻繁而簡單的恢復保存在內存中;會議紀要。
定義:在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態,這樣之後就能夠將該對象恢復到原先保存的狀態。
備忘錄模式中,須要保存狀態的對象咱們叫發起者,咱們會定義一個備忘錄類,發起者類上會定義一個保存狀態到備忘錄類的方法及相應提早狀態方法。備忘錄類負責存儲發起者的狀態(不提供get/set),把要保持的細節都封裝在備忘錄類上。再有一個即是備忘錄類管理者(提供備忘錄類對象的get/set方法)。負責保存備忘錄類和提升備忘錄類給發起者。
備忘錄模式適合功能比較複雜,須要維護和記錄屬性歷史的類,用於還原備份的信息到前一狀態。還有在使用命令模式時,須要實現命令的撤銷功能時,可使用備忘錄模式存儲可撤銷操做的狀態。
缺點:若是要備份的狀態數據很大不少時,備忘錄對象會很是消耗內存資源。
組合模式
定義:將對象組合成樹形結構以表示 部分-總體 的層次結構。組合模式使得用戶對單個對象和組合對象的使用具備一致性。
和HeadFirst設計模式(中文版)中說的組合模式描述不太相同,待確認。個人理解通常一個組件或者類中集合了其餘功能組件最後就組合成了一個功能,這就是一種組合模式,如各個零部件組合成了手機。
當需求中體現部分和總體層次的結構時,但願用戶能夠忽略組合對象與單個對象的不一樣,統一地使用組合結構中的因此對象時,考慮使用組合模式。
使用組合模式,用戶不要關心究竟是處理一個葉節點仍是處理一個組合組件,也就用不着爲定義組合而寫一些選擇判斷語句了。即組合模式讓客戶能夠一致地使用組合結構和單個對象。
待對比!!!
迭代器模式
例子:售票員售票,無論是人是物,只要上次就要買票。java裏的迭代器遍歷各類數據結構.foreach;iterator
定義:提供一種方法順序訪問一個聚合對象(數據結構集合)中各個元素,而又不暴露該對象的內部表示。(什麼叫內部表示?)
當咱們須要訪問一個彙集對象,並且無論這些對象是什麼都須要遍歷的時候,應該考慮用迭代器模式。
迭代器模式即一個彙集抽象類,一個跌倒抽象類。在具體繼承的彙集類裏有個建立迭代器的方法,而在具體的迭代器裏有對應彙集類的具體迭代器類,並定義了一個具體彙集對象的屬性,用於在重寫迭代器方法時用具體對象來完成相應的方法。
迭代器模式分離了集合對象的遍歷行爲,抽象出一個迭代器類來負責,這樣既能夠作到不暴露集合的內部結構,又可讓外部代碼透明地訪問集合內部的數據。
單例模式
例子:只要一個數據庫鏈接池;只要一個賴榮鋒;只要一個創造工廠;
單例模式是否實例化應該由單例對象自身判斷,經過構造方法私有來實現。不過如今java單例模式的寫法通常是經過延遲初始化佔位類模式來實現。
定義:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
防止一個類實例化多個對象的最好辦法是讓類自身負責保存它的惟一實例。
通常單例類提供私有化的構造函數,並提供公有化靜態方法來獲取對象,去建立或訪問單例類的惟一實例。
多線程時用雙重檢查加鎖或者延遲初始化佔位類模式來實現。通常用延遲初始化佔位類模式比較好。
橋接模式
利用的原則是:合成(組合)/聚合複用原則。即優先使用對象合成/聚合,而不是類繼承。大雁和它的翅膀是合成或者說叫組合關係,而大雁和雁羣是聚合關係。二者之間的區別是強擁有和弱擁有的關係,組合體現了嚴格的部分和總體的關係,部分和總體的生命週期同樣。而聚合是指雁羣能夠保護大雁,但大雁並非雁羣的一部分,能夠很輕鬆地脫離關係。
優先使用對象的合成聚合有助於保持每一個類被封裝,並被集中在單個任務上,使得類與類繼承層次保持較小規模。
面向接口編程,經過接口組裝出想要的功能,繼承太笨重。
定義:將抽象部分與他的實現部分分離,使它們均可以獨立地變化。
兩個抽象類之間有一條聚合線,像一座橋,因此叫橋接模式。
橋接模式是因爲一個對象或者說功能的實現方式有不少種,如手機能夠按品牌來分實現,也能夠按照功能來分,而橋接模式的核心意圖就是把這些實現獨立出來,讓他們各自地變化,這樣就使得實現的變化不會影響其餘實現,達到開發關閉的拓展原則,得以應對後續的變化。
如手機,有功能抽象類,下面有通信錄,照相機等功能實現,還有品牌抽象類,下面有蘋果,小米等實現,在如蘋果的實現類中其有設置功能抽象類進來的入參,使得蘋果能夠聚合通信錄,照相機等功能,然後面無論添加新的品牌或者功能,都只須要在各類中擴展便可,不須要重複。
當實現系統可能有多角度分類,每一種分類都有可能變化,那麼就能夠把這種多角度分離出來讓他們獨立變化,減小他們之間的耦合。也就是橋接模式。
例子:手機的功能和品牌區分。汽車的品牌和使用的驅動燃料不一樣的區分。
命令模式
例子:餐廳點餐;軍隊指揮,司令員經過通信兵傳達信息命令。
適用場景:當行爲請求者和行爲實現者緊耦合,且對請求排隊或記錄請求日誌,以及支持可撤銷的操做等行爲時。
定義:將一個請求封裝爲一個對象,從而使你能夠用不一樣的請求對客戶進行參數化(什麼意思?);對請求排隊或記錄請求日誌,以及支持可撤銷的操做。
通常是客戶端經過一個專門的調用者如服務員(包含一個命令集List)發出命令,命令類接口底下實現各類命令類(包含一個接受者對象),而每一個具體的命令類對應有接收命令的執行者,接受命令的執行者類作出真正的動做。
優勢:
其餘:敏捷開發原則告訴咱們,不要爲代碼添加基於猜想的、實際不須要的功能。
職責鏈模式
定義:使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將這個對象連成一條鏈,並沿着這條鏈傳遞該請求,知道有一個對象處理它爲止。
定義一個職責類handler接口,具體的處理類實現該接口,處理它負責的請求,每一個具體的處理類都會有個後繼者屬性set進來,若是是能夠處理的請求則處理掉,如不不是則將該請求轉發給set進來的後繼者去處理。後繼者就是另外一個具體的處理類,這樣一直請求下去。
好處:當客戶提交一個請求時,請求是沿着請求鏈傳遞直至有一個具體的處理類對象福州處理它。接受者和發送者都沒有對方的明確信息,簡化了職責鏈可簡化對象的相互鏈接,由於它只須要保持一個指向其後繼者的引用,而不須要保持因此的候選接受者的引用,極大下降了耦合度。
中介者模式
又叫調停者模式
例子:房產中介;簽證中介;二手車中介;聯合國;計算器中經過form窗體做爲中介者來完成控件的交互。
前提:大量的鏈接使得一個對象不可能在沒有其餘對象的支持下工做,系統表現爲一個不可分割的總體,而這樣對系統的行爲進行任何較大的改動就比較困難,所以有個同一個鏈接中介能夠大大減小大量的鏈接,經過鏈接這個中介對象便能得到想要的全部鏈接(如國與國之間經過聯合國發生關係),豈不美哉.哈哈哈哈哈哈哈哈哈哈(迪米特原則)
經過中介者對象,能夠將系統的網狀結構變成以中介者爲中心的星形結構。
定義:用一箇中介對象來封裝一系列的對象交互。中介者使各對象不須要顯式地相互引用,從而使其耦合鬆散,並且能夠獨立地改變它們之間的交互。
通常定義一箇中介者抽象類和一個同事抽象類,具體中介者基礎該中介者抽象類,裏面包含全部的同事屬性,經過set方法set進來,並實現抽象類中用來交互的抽象消息發送方法;而具體同事類則實現同事抽象類,經過構造方法參數在建立同事類時把中介者對象添加進來,並提供發送和接收消息的方法。
在具體實踐中,中介者類是否要抽象或者接口取決於將來是否須要擴展中介者對象,好比聯合國除了安理會還有世界衛生組織,教科文組織等。
當系統出現了 「多對多」 交互複雜的對象羣時,不要急於使用中介者模式,而要先反思你的系統在設計上是否是合理。
優勢:減小了各個同事類的耦合,使得能夠獨立的修改和複用各個同事類和中介者類;使得咱們能夠站在更宏觀的角度去看系統,因爲把對象如何協做進行了抽象,將中介做爲一個獨立的概念並將其封裝在一個對象中,這樣關注的對象就從對象各類自己的行爲轉移到天明直接的交互上來。從無數的雙邊關係轉移到聯合國關係上來。
缺點:因爲中介者類控制集中化,因而就把交互複雜性變成了中介者的複雜性,使得中介者複雜度直線升高。
優勢來着集中控制,缺點也來着集中控制,因此使用該模式時要考慮清楚。
通常應用於一組對象已定義良好可是交互通訊複雜的場合,或者是想定製一個分佈在多個類中的行爲,而又不行生成太多的子類的場合(其實就是經過組合引用該行爲功能吧?)。
享元模式
例子:博客網站;微博;郵箱;電商;字符串String;圍棋、五子棋、跳棋(大量的棋子對象,使用享元最合適不過,如圍棋建立兩個黑白棋子的享元對象,外部狀態爲方位座標)
定義:運用共享技術有效地支持大量細粒度的對象。
使用時會建立一個享元工廠,享元工廠裏有個保存享元對象的hashtable集,讓用戶經過key/value形式獲取享元對象,用來建立享元對象(Flyweight),一個享元抽象類,具體有實際的享元類,和不分享的實例享元類,客戶端經過調用享元工廠得到享元對象,享元工廠在建立享元對象時經過參數傳入外部狀態。
內外部狀態:在享元對象內部而且不會隨環境改變而改變的共享部分,爲享元對象的內部狀態;
隨環境改變而改變、不能夠共享的狀態就是外部狀態了。
享元模式能夠避免大量很是類似類的開銷。在程序設計中,有時須要生成大量細粒度的類實例來表示數據。若是能發現這些實例除了幾個參數外基本上都是相同的,使用享元模式便可以大幅度地減小須要實例化的類的數量。若是能把不一樣的地方一道類實例外面,在方法調用時將它們傳遞進來,就能夠用經過共享大幅度地減小單個實施例的數目。
適用場景:若是一個應用程序使用了大量的對象,而大量的這些對象形成了很大的存儲開銷時就應該考慮使用;還有就是對象的大多數狀態能夠外部狀態,若是刪除對象的外部狀態,那麼能夠用相對較少的共享對象取代不少組對象,此時能夠考慮使用享元模式。直觀體現即是使用享元模式,實例總數大大減小了。
解釋器模式
例子:不一樣瀏覽器解釋HTML語言展現頁面;正則表達式;曲譜演奏解釋器;java虛擬機解釋器;
定義:給定一個語言,定義他的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
若是一種特定類型的問題發生的頻率足夠高,那麼可能就值得將該問題的各個實例表述爲一個簡單語言中的句子,這樣就能夠構建一個解釋器,該解釋器經過解釋這些句子來解決該問題。
通常是一個context類存放要解釋的內容,一個抽象表達式類,包括解釋和執行兩個方法,經過簡單功能加反射來決定具體選擇哪一種具體表達式類解釋執行。
用解釋器模式,至關於開發了一個編程語言或腳本給本身或別人用。解釋器模式就是用 ‘迷你語言’ 來表現程序要解決的問題,以迷你語言寫成 ‘迷你程序’ 來表現具體的問題。
當有一個語言須要解釋執行,而且你能夠將該語言中的句子表示爲一個抽象語法樹時(?),可以使用解釋器模式。
只要是能夠用語言來描述的,均可以應用解釋器模式。
優勢:容易改變和擴展文法,由於該模式使用類來表示文法規則,咱們可使用繼承來改變或擴展該文法;也比較容易實現文法,由於定義抽象語法樹中各個節點的類的實現大致相似,這些類都易於直接編寫。
缺點:由於解釋器爲文法中的每一條規則至少定義了一個類,所以包含許多規則的文法可能難以管理和維護。
因此當文法很是複雜時,使用語法分析程序或編譯器生成器來代替處理。
訪問者模式
定義:表示一個做用於某對象結構中的各元素的操做。它使你能夠在不改變各元素的類的前提下定義做用於這些元素的新操做。
訪問者模式使用時必須肯定element元素是肯定的,這樣才能在狀態(visitor)類上定義肯定個數element的方法。一個抽象的element類,他有一個接受狀態(visitor)參數的方法,底下具體實現如男人、女兒這樣肯定的具體元素。還有一個抽象的狀態visitor類,他有對應不一樣元素的抽象方法,如男人的反應、女人的反應兩個方法。具體的狀態實現該抽象分別寫出不一樣狀態下男女不一樣的反應。另外有個對象結構(ObjectStructure),用於不一樣元素對應的邏輯展現,如針對不一樣的 ’狀態‘ 遍歷 男人 和 女人 ,獲得不一樣的反應。客戶端經過對象結構,添加元素如男人、女人。而後建立不一樣的狀態,做爲參數傳遞給對象結構展現方法,展現方法把狀態做爲參數傳遞給男人、女人,讓男人女人經過接受這個方法加狀態參數來調用各自男女不一樣的方法。
訪問者模式適用於數據結構相對穩定的系統,它吧書畫家結構和做用於結構上的操做之間的耦合解開,使得操做計劃能夠相對自由地演化。
目的:把處理從數據結構中分離出來,使得算法操做的增長變得容易。當有比較穩定的數據結構,又有易於變化的算法的話,使用訪問者模式是比較合適的。
優勢:增長新的操做很容易,由於增長新的操做意味着只要增長一個新的訪問者,訪問者模式將有關的行爲集中到一個訪問者對象中。
缺點:增長新的數據結構變得困難。大多數狀況下很難找到數據結構不變化的狀況,所以不多使用訪問者模式
給各個設計模式加上UML圖及再學習下第一章中UML圖怎麼使用。