1 迭代器模式
解決問題:主要是多個類的話,搜尋出相應(yīng)的個股并逐個打印出來,這個在調(diào)用類的過程中坤按,會產(chǎn)生較多的for循環(huán)或者while循環(huán)。如果多個調(diào)用類的話馒过,在調(diào)用類中寫不好并且重復(fù)多遍臭脓。
設(shè)計思路:迭代模式,先定義號迭代器接口沉桌,里面有循環(huán)迭代的接口谢鹊,然后定義一個迭代器類繼承迭代器接口算吩,實現(xiàn)循環(huán)迭代的接口。然后在容器接口中調(diào)用迭代器的類佃扼,以實現(xiàn)循環(huán)迭代的效果偎巢,再生成一個容器類來繼承容器接口來寫定義好的方法。最后調(diào)用類直接調(diào)用容器類提供的接口兼耀,即可實現(xiàn)循環(huán)遍歷查詢的目的
常用場景:數(shù)據(jù)庫的cursor游標(biāo)
github地址:
2 模版方法模式
解決問題:有很多開發(fā)中固定的關(guān)鍵步驟压昼,并確定了這些步驟的執(zhí)行順序,但是具體步驟會隨著環(huán)境的變化而變化瘤运。譬如電腦開機的步驟:開啟電源->硬件檢查->加載系統(tǒng)->登錄->關(guān)閉窍霞,程序員的計算機多了一部輸入密碼登錄,軍方的計算機多了指紋登錄外拯坟,不僅要硬件檢查但金,還要加多一部做防火墻檢查
設(shè)計思路:模版方式模式,先定義一個抽象類郁季,先定義基本的方法冷溃,然后最后final一個方法實現(xiàn)按順序走必須要走的方法;然后根據(jù)需求新的類梦裂,繼承抽象類似枕,重寫抽象類中需要增加的方法,如果沿用抽象類的方法年柠,保留 super.fun()凿歼,;既走父類的方法冗恨,也走自己的方法答憔,在 super.fun() 寫新的實現(xiàn)代碼;不走父類的方法派近,直接抹掉 super.fun()
常用場景:AsyncTask
github地址:https://github.com/tjjlhst/JavaDesignProject/tree/master/MasterplateModule
3 訪問者模式
解決問題:1攀唯、對象結(jié)構(gòu)比較穩(wěn)定,但經(jīng)常需要在此對象上定義新的操作 2渴丸、需要對一個對象結(jié)構(gòu)中的對象進行很多不同的并且不相關(guān)的操作侯嘀,而需要避免污染這些對象的類,也不希望在增加新操作時修改這些類
設(shè)計思路:訪問者模式比較復(fù)雜谱轨,首先定義為角色的分配戒幔,以員工和老板為例,cto土童、ceo = visitor诗茎,擁有查看員工信息的權(quán)限,經(jīng)理、工程師 = staff敢订;首先staff被查看者都定義一個可以查看的權(quán)限王污,visitor只有權(quán)限才能查看,然后定義子類需要的值楚午,構(gòu)建經(jīng)理和工程師兩個子類昭齐,這兩個子類利用staff的值,寫各自獨有的方法矾柜;然后定義接口類visitor的方法阱驾,寫兩個相同的方法visit(),但是傳的是兩個不同的staff類的參數(shù)怪蔑,然后構(gòu)建兩個繼承visitor的ceo和cto類里覆,它們的方法分別是調(diào)用查看經(jīng)理和工程師的信息方法visit() (通過參數(shù)的不同來區(qū)分)
常用場景:
github地址:https://github.com/tjjlhst/JavaDesignProject/tree/master/AccessModule
4 中介者模式
解決問題:當(dāng)對象之間的交互操作很多且每個對象的行為都彼此依賴時,為防止在修改一個對象的行為時缆瓣,同時涉及修改很多其他對象的行為喧枷,可用中介模式來解決緊耦合的問題。該模式由多對多變成一對多的關(guān)系弓坞,將系統(tǒng)從網(wǎng)狀結(jié)構(gòu)變成以調(diào)停者為中心的星形結(jié)構(gòu)割去,達(dá)到降低系統(tǒng)的復(fù)雜性,提高可擴展性的作用
設(shè)計思路:將對象的行為和協(xié)作抽象化昼丑,把對象在小尺度的行為上與其他對象的相互作用分開處理,
常用場景:keyguard鎖屏
github地址:
5 代理模式(委托模式)
解決問題:當(dāng)無法或不想直接訪問某個對象或訪問某個對象存在困難的時候可以通過一個代理對象來間接訪問夸赫,為了保證客戶端使用的透明性菩帝,委托對象與代理對象需要實現(xiàn)相同的接口
設(shè)計思路:結(jié)構(gòu)性模式。以討薪走法律流程為例茬腿,1呼奢、(靜態(tài)代理)首先先定義一個接口類,定義好上述固定的步驟: 申訴->舉證->辯護->完成 四個方法切平;定義具體訴訟類握础,繼承訴訟接口類,重寫接口類的方法悴品;定義具體代理類禀综,持有一個具體被代理者的引用,實例化代理類時要把訴訟類傳進來成為引用苔严,代理類的四個規(guī)定步驟定枷,走的全是訴訟類的相同方法(也就是代理類只是作為一個代理轉(zhuǎn)達(dá)消息,并沒有實質(zhì)自己要做的事)届氢;調(diào)用類用接口類構(gòu)造一個具體的訴訟類欠窒,再創(chuàng)建一個代理類,將構(gòu)建好的訴訟類傳入代理類中退子,代理按照步驟將方法逐個調(diào)用岖妄。2型将、(動態(tài)代理)通過反射的機制動態(tài)地生成代理者的對象,也就是在code階段壓根不知道代理誰荐虐,在有在執(zhí)行階段才知道(java提供了動態(tài)代理接口InvocationHandler七兜,實現(xiàn)該接口需要重寫其調(diào)用的invoke()方法);先聲明一個object的引用缚俏,該引用將指向被代理類惊搏,而我們調(diào)用被代理類的具體方法則在invoke方法中執(zhí)行,實例化動態(tài)代理后忧换,繼續(xù)按步驟調(diào)用固定的方法即可
常用場景:Binder跨進程通信機制與AIDL
github地址:https://github.com/tjjlhst/JavaDesignProject/tree/master/ProxyModule
6 組合模式
解決問題:將一組相似的類看作一個對象來處理恬惯,并根據(jù)一個樹狀結(jié)構(gòu)來組合對象,然后提供一個統(tǒng)一的方法去訪問相應(yīng)的對象亚茬,以此忽略掉對象與對象集合之間的差異酪耳。不同的對象根據(jù)抽象的基類的抽象方法,定義該對象的類能否實現(xiàn)該功能刹缝,譬如文件夾和文件的功能區(qū)分碗暗,文件夾下能加文件,而文件下不能加文件
設(shè)計思路:以文件來舉例梢夯,先定義抽象的基類Dir言疗,然后定義抽象的方法;定義文件夾類Folder繼承Dir颂砸,實現(xiàn)Dir類的添加文件噪奄、移除文件等方法;定義文件類File繼承Dir人乓,實現(xiàn)Dir類的print打印方法勤篮,不能實現(xiàn)添加文件、移除文件等方法色罚。在調(diào)用類使用時碰缔,文件夾下可以添加文件或文件夾,文件下不能添加文件夾或文件
常用場景:View和ViewGroup戳护,vViewGroup有容器的功能
github地址:https://github.com/tjjlhst/JavaDesignProject/tree/master/CompositeModule
7 適配器模式
解決問題:需要對兩個無關(guān)系的兩個類融合到一起金抡,將不同的的東西通過一種轉(zhuǎn)換使它們能夠協(xié)作起來,listview腌且、recycleview都需要使用到adapter竟终,adapter就是 混血 接口,將兩個不同類的兩種不同接口進行兼容切蟋,在不修改原有代碼的情況下滿足需求
設(shè)計思路:角色介紹:
Target:目標(biāo)角色统捶,也就是所期待獲得的接口
Adaptee:現(xiàn)在需要適配的接口
Adapter:適配器角色,適配器需要把源接口轉(zhuǎn)換成目標(biāo)接口。所以adapter這一角色不可以是接口喘鸟,必須是具體類
可以定義多個不同的類匆绣,最后都通過adapter統(tǒng)一轉(zhuǎn)成一個結(jié)果即可,譬如有5v什黑、110v和220v的輸入功率類崎淳,但是最后通過自定義adapter均轉(zhuǎn)成5v的結(jié)果即可
常用場景:listview和recycleview的adapter使用
github地址:https://github.com/tjjlhst/JavaDesignProject/tree/master/AdapterModule
8 裝飾模式
解決問題:動態(tài)地給一個對象添加一些額外的職責(zé),就增加功能來說愕把,裝飾模式相比生成子類更加靈活拣凹。在需要透明且動態(tài)地擴展類的功能時
設(shè)計思路:角色介紹:
Component:抽象組件:可以是一個接口或抽象類,其充當(dāng)?shù)木褪潜谎b飾的原始對象
ConcreteComponent:組件具體實現(xiàn)類:該類是Component類的基本實現(xiàn)恨豁,也是我們裝飾的具體對象
Decorator:抽象裝飾者:其承擔(dān)的責(zé)任就是為了裝飾我們的組件對象嚣镜,其內(nèi)部一定有一個指向組件對象的引用,在大多情況下該類為抽象類橘蜜,需要根據(jù)不同的裝飾邏輯實現(xiàn)不同的具體子類
ConcreteDecoratorA/ConcreteDecoratorB:具體實現(xiàn)類
常用場景:Context與ContextImpl
github地址:https://github.com/tjjlhst/JavaDesignProject/tree/master/DecoratorModule
9 享元模式
解決問題:對象池的一種實現(xiàn)淑履,輕量級形用,用來盡可能的減少內(nèi)存使用量芹务,適用于可能存在大量重復(fù)對象的場景薄湿,緩存可共享的對象。
設(shè)計思路:共享對象分為內(nèi)部對象和外部對象象颖,可共享的對象稱為內(nèi)部對象佩厚,內(nèi)部對象不會隨著環(huán)境改變;不可共享的狀態(tài)稱之為外部狀態(tài)说订,它們會隨著環(huán)境變化而變化可款。在享元模式中會建立一個元對象容器,經(jīng)典的享元模式中該容器為一個map克蚂,鍵就是享元對象的內(nèi)部對象,值就是享元對象本身筋讨。以買票為例埃叭,同一個地點的車輛是有限的,這些就可以存起來悉罕,查詢的時候直接調(diào)用不創(chuàng)建新的對象赤屋,先創(chuàng)建一個ticket接口,該接口定義展示車票信息的函數(shù)壁袄;然后新建一個TicketFactory類类早,定義一個static方法getTicket(from,to),這里的from嗜逻、to拼接就相當(dāng)于做享元模式的key用涩僻,然后用key做判斷,如果沒有這個key,就新建一個TicketFactory對象返回逆日,如果有嵌巷,方法直接返回已有的TicketFactory;在測試類中室抽,直接調(diào)用TicketFactory類的getTicket(from,to)方法
常用場景:1 存在大量相似的相似對象 2 細(xì)粒度的對象都具備接近的外部狀態(tài)搪哪,而且內(nèi)部狀態(tài)與環(huán)境無關(guān),也就是說對象沒有特定身份 3 需要緩沖池的情景
Handler坪圾、Message晓折、android消息機制
github地址:https://github.com/tjjlhst/JavaDesignProject/tree/master/FlyweightModule
10 外觀觀式
解決問題:就是統(tǒng)一接口封裝,將子系統(tǒng)的邏輯兽泄、交互都隱藏起來漓概,為用戶提供了一個高層次的接口,使得系統(tǒng)更加易用已日,同時也對外隱藏了具體的實現(xiàn)垛耳。即使具體的子類發(fā)生了改變,用戶也不會感知到
設(shè)計思路:以手機為例飘千,先建立一個MobilePhone類堂鲜,它有兩個子功能撥號和拍照,MobilePhone可以封裝起來提供統(tǒng)一的操作接口护奈,只需要通過MobilePhone就可以打電話和拍照缔莲,用戶可以忽略子功能背后做的一系列動作;定義一個phone接口和phoneImpl類霉旗,實現(xiàn)打電話的功能痴奏;定義一個camera接口和cameraImpl類,實現(xiàn)拍照功能厌秒;MobilePhone類中創(chuàng)建phone和camera的實類读拆,定義調(diào)用它們打電話或拍照的方法,并提供給test類調(diào)用鸵闪,即可檐晕。所以內(nèi)部還可以增加Message接口和MessageImpl類,MobilePhone增加調(diào)用的方法蚌讼,test類也不需要改動辟灰,只要調(diào)用新增的方法即可
常用場景:Context
github地址:
11 Builder模式
解決問題:是讓用戶在清楚流程的情況下一步一步創(chuàng)建一個復(fù)雜對象的創(chuàng)建模式,可以更精細(xì)地控制對象的構(gòu)造流程篡石。該模式是為了將構(gòu)建復(fù)雜對象的過程和它的部件解耦芥喇,使得整個過程和部件的表示隔離開來,使用場景1凰萨、相同的方法继控,不同的執(zhí)行順序械馆,產(chǎn)生不同的事件結(jié)果時 2、多個部件或零件湿诊,都可以裝配到一個對象中狱杰,但是產(chǎn)生的運行時結(jié)果又不相同 3、產(chǎn)品非常復(fù)雜厅须,或者產(chǎn)品類中的調(diào)用順序不同產(chǎn)生了不同的作用仿畸,這個時候使用建造者模式非常合適 4 初始化一個對象特別復(fù)雜,如參數(shù)很多朗和,且很多參數(shù)都具有默認(rèn)值時
設(shè)計思路:Builder和Director兩個類一起將一個復(fù)雜對象的構(gòu)建與分離错沽,director會對builder進行創(chuàng)建并封裝起來,但不夠靈活眶拉;如果需要靈活應(yīng)用可以直接用builder設(shè)置需要的參數(shù)千埃;如果builder要做到鏈?zhǔn)降木幊蹋赽uilder的每個方法中return this才行
常用場景:AlertDialog.Builder
github地址:https://github.com/tjjlhst/JavaDesignProject/tree/master/BuilderModule