摘要:維基百科抽象工廠的例子構(gòu)建模式當(dāng)構(gòu)建一個(gè)復(fù)雜對(duì)象時(shí),就可以使用建造者模式。在中,類中的方法就是適配器模式的例子,把一個(gè)數(shù)組轉(zhuǎn)換為一個(gè)集合。這種設(shè)計(jì)模式的好處是方便添加一種車巴士,只需要繼承類。
寫在前面
評(píng)判一個(gè)程序員是否優(yōu)秀,就是 show me the code。優(yōu)秀的代碼可讀性強(qiáng),高內(nèi)聚低耦合,可擴(kuò)展。想要寫優(yōu)秀的代碼,做個(gè)優(yōu)秀的程序員,就需要多看看大牛寫的開源框架,吸取其中的精華,多學(xué)學(xué)設(shè)計(jì)模式,除此之外,沒有任何其他捷徑。
設(shè)計(jì)模式主要分為創(chuàng)建型模式、結(jié)構(gòu)型模式、行為型模式三種類型。
工廠方法(Factory method pattern)定義一個(gè)創(chuàng)建對(duì)象的接口,讓實(shí)現(xiàn)這個(gè)接口的類來決定實(shí)例化哪個(gè)類。工廠方法讓類的實(shí)例化推遲到子類中進(jìn)行,它屬于創(chuàng)建型模式。
工廠對(duì)象通常包含一個(gè)或多個(gè)方法,用來創(chuàng)建這個(gè)工廠所能創(chuàng)建的各種類型的對(duì)象。這些方法可能接收參數(shù),用來指定對(duì)象創(chuàng)建的方式,最后返回創(chuàng)建的對(duì)象。
工廠通常是一個(gè)用來創(chuàng)建其他對(duì)象的對(duì)象。工廠是構(gòu)造方法的抽象,用來實(shí)現(xiàn)不同的分配方案。
維基百科工廠方法的例子
// 定義了 Button 如何創(chuàng)建 public interface Button{} // 實(shí)現(xiàn)了 WinButton public class WinButton implements Button{} // 實(shí)現(xiàn)了 MacButton public class MacButton implements Button{} // 創(chuàng)建 Button 的工廠類 public interface ButtonFactory { Button createButton(); } // 真正創(chuàng)建 WinButton 的實(shí)現(xiàn)類,實(shí)現(xiàn)了 ButtonFactory public class WinButtonFactory implements ButtonFactory { @Override public static Button createButton(){ return new WinButton(); } } // 真正創(chuàng)建 MacButton的實(shí)現(xiàn)類,實(shí)現(xiàn)了 ButtonFactory public class MacButtonFactory implements ButtonFactory { @Override public static Button createButton(){ return new MacButton(); } }抽象工廠模式(Abstract factory pattern)
將一組具有同一主題的多帶帶的工廠封裝起來。在使用中,使用方需要?jiǎng)?chuàng)建抽象工廠的具體實(shí)現(xiàn),然后使用抽象工廠作為接口來創(chuàng)建這一方法的具體對(duì)象。它屬于創(chuàng)建型模式。
抽象工廠就好像是對(duì)工廠方法的一種擴(kuò)展,有個(gè)產(chǎn)品族的概念,也就是一堆產(chǎn)品。上面的工廠方法就一個(gè)產(chǎn)品(Button),而下面抽象工廠的例子里有兩個(gè)產(chǎn)品(Button和 Border)。
抽象工廠的優(yōu)點(diǎn):
具體產(chǎn)品從客戶代碼中被分離出來。
容易改變產(chǎn)品的系列。
將一個(gè)系列的產(chǎn)品族統(tǒng)一到一起創(chuàng)建。
抽象工廠的缺點(diǎn):
在產(chǎn)品族中擴(kuò)展新的產(chǎn)品是很困難的,它需要修改抽象工廠的接口。
維基百科抽象工廠的例子
public interface Button {} public interface Border {} public class WinButton implements Button {} public class WinBorder implements Border {} public class MacButton implements Button {} public class MacBorder implements Border {} public interface AbstractFactory { Button createButton(); Border createBorder(); } public class WinFactory { @Override public static Button createButton() { return new WinButton(); } @Override public static Border createBorder() { return new WinBorder(); } } public class MacFactory { @Override public static Button createButton() { return new MacButton(); } @Override public static Border createBorder() { return new MacBorder(); } }構(gòu)建模式(Builder pattern)
當(dāng)構(gòu)建一個(gè)復(fù)雜對(duì)象時(shí),就可以使用建造者模式。它實(shí)際上就是傳入一個(gè)參數(shù),然后返回對(duì)象本身,方便下一個(gè)屬性或者參數(shù)來構(gòu)建??梢园葱铇?gòu)建對(duì)象,可擴(kuò)展性強(qiáng)。它屬于創(chuàng)建型模式。
在 JDK 中,StringBuilder 類的 append() 方法就是一個(gè)很好的構(gòu)建模式例子。
// java.lang.StringBuilder @Override public StringBuilder append(CharSequence s) { super.append(s); return this; }原型模式(Prototype pattern)
它的特點(diǎn)在于通過 復(fù)制 一個(gè)已經(jīng)存在的實(shí)例來返回新的實(shí)例,而不是新建實(shí)例。被復(fù)制的實(shí)例就是我們所稱的原型,這個(gè)原型是可定制的。它屬于創(chuàng)建型模式。
原型模式多用于創(chuàng)建復(fù)雜的或者耗時(shí)的實(shí)例,因?yàn)檫@種情況下,復(fù)制一個(gè)已經(jīng)存在的實(shí)例使程序運(yùn)行更高效,它們實(shí)際上就是命名不一樣的同類數(shù)據(jù)。
在 JDK 中,Object 類中的 clone() 方法就是典型的原型模式。
//在具體的實(shí)現(xiàn)類里可以直接重寫 clone() 方法 protected native Object clone() throws CloneNotSupportedException;單例模式(Singleton pattern)
不管在任何時(shí)候,獲取一個(gè)對(duì)象時(shí)只會(huì)返回同一個(gè)實(shí)例。通常我們?cè)诙甲x取配置文件時(shí),文件里的內(nèi)容是不變的,因此我們就可以使用單例模式來實(shí)現(xiàn)。它屬于創(chuàng)建型模式。
單例模式很簡(jiǎn)單,只需要三步就完成,下面是 JDK 里的 Runtime 類實(shí)現(xiàn)的單例模式。
public class Runtime { // 1.new 一個(gè)私有的靜態(tài)的 Runtime 實(shí)例 private static Runtime currentRuntime = new Runtime(); // 2.返回當(dāng)前應(yīng)用的 Runtime 實(shí)例 public static Runtime getRuntime() { return currentRuntime; } // 3.私有化構(gòu)造方法,不允許在其它類構(gòu)造 Runtime 實(shí)例 private Runtime() {} }適配器模式(Adapter pattern)
適配器模式也稱作包裝(wrapper),它屬于結(jié)構(gòu)型模式。
它的作用是把原本兩個(gè)不兼容的接口通過一個(gè)適配器或者包裝成兼容的接口,然后它們可以一起工作。例如我們的手機(jī)數(shù)據(jù)線,就好比是一個(gè)適配器,一端是 USB接口,一端是 Type-C 或者 Lightning 接口,本來它們是不能一起工作的,但我們用這跟數(shù)據(jù)線(適配器)就可以讓它們協(xié)同工作了。
它的優(yōu)點(diǎn):
1.可以讓任何兩個(gè)沒有關(guān)聯(lián)的接口一起工作。
2.提高了接口的復(fù)用。
3.增加了接口的透明度。
4.靈活性好。
它的缺點(diǎn):
1.過多地使用適配器,會(huì)讓系統(tǒng)非常零亂,不易整體進(jìn)行把握。
2.由于 JAVA 只能繼承一個(gè)類,所以最多只能適配一個(gè)適配者類,而且目標(biāo)類必須是抽象類。
在 JDK 中,Arrays 類中的 asList(T... a) 方法就是適配器模式的例子,把一個(gè)數(shù)組轉(zhuǎn)換為一個(gè)集合。
public staticList asList(T... a) { return new ArrayList<>(a); }
在 JDK 中,Collections 工具類的 list() 方法把枚舉轉(zhuǎn)集合。
public staticArrayList list(Enumeration e) { ArrayList l = new ArrayList<>(); while (e.hasMoreElements()) l.add(e.nextElement()); return l; }
當(dāng)然,這上面兩個(gè)例子是非常簡(jiǎn)單的,好像看不出來使用了任何的設(shè)計(jì)模式,跟我們平時(shí)使用的轉(zhuǎn)換一模一樣。這里只是一個(gè)理念的介紹,實(shí)際上,在使用中是用一個(gè)中間的 Adapter 類來做兼容或者包裝的。
橋接模式(Bridge pattern)將抽象與其實(shí)現(xiàn)分離,以便兩者可以獨(dú)立變化。它屬于結(jié)構(gòu)型模式。
當(dāng)一個(gè)類經(jīng)常變化時(shí),面向?qū)ο缶幊痰奶匦宰兊梅浅S杏?,因?yàn)榭梢杂米钌俚年P(guān)于程序的先驗(yàn)知識(shí)來容易地改變程序的代碼。當(dāng)類和它經(jīng)常變化時(shí),橋模式很有用。類本身可以被認(rèn)為是抽象,類可以作為實(shí)現(xiàn)來做。橋模式也可以被認(rèn)為是兩層抽象。
它通過提供抽象化和實(shí)現(xiàn)化之間的橋接結(jié)構(gòu),來實(shí)現(xiàn)二者的解耦。
它的優(yōu)點(diǎn):
1.抽象和實(shí)現(xiàn)分離開。
2.優(yōu)秀的擴(kuò)展能力。
3.實(shí)現(xiàn)細(xì)節(jié)對(duì)調(diào)用方透明。
它的缺點(diǎn):
橋接模式的引入會(huì)增加系統(tǒng)的理解與設(shè)計(jì)難度,由于聚合關(guān)聯(lián)關(guān)系建立在抽象層,需要針對(duì)抽象進(jìn)行設(shè)計(jì)與編程,加深編程難度。
這是個(gè)生產(chǎn)不同車輛和需要不同生產(chǎn)流程的例子。首先,定義一個(gè)車輛(Vehicle)的抽象接口,里面有個(gè)生產(chǎn)車輛的對(duì)應(yīng)流程集合和一個(gè)生產(chǎn)的抽象方法。然后是自行車(Bike)和汽車(Car)對(duì)抽象接口的實(shí)現(xiàn)。然后定義一個(gè)生產(chǎn)車輛需要的流程(WorkShop),它有兩個(gè)實(shí)現(xiàn) ProduceWorkShop 和 TestWorkShop。最后,main 方法的代碼就是對(duì)這個(gè)橋接模式的使用方式。
這種設(shè)計(jì)模式的好處是方便添加一種車巴士(Bus),只需要繼承 Vehicle 類。也非常方便的添加一種生產(chǎn)流程噴漆(PaintWorkShop),只需要繼承 WorkShop 類即可,擴(kuò)展性很高。
//車輛的抽象接口 public abstract class Vehicle { // protected Listworkshops = new ArrayList (); public Vehicle() { super(); } public boolean joinWorkshop(WorkShop workshop) { return workshops.add(workshop); } public abstract void manufacture(); } //自行車的實(shí)現(xiàn) public class Bike extends Vehicle { @Override public void manufacture() { System.out.println("Manufactoring Bike..."); workshops.stream().forEach(workshop -> workshop.work(this)); } } //汽車的實(shí)現(xiàn) public class Car extends Vehicle { @Override public void manufacture() { System.out.println("Manufactoring Car"); workshops.stream().forEach(workshop -> workshop.work(this)); } } //生產(chǎn)車的抽象接口 public abstract class WorkShop { public abstract void work(Vehicle vehicle); } //制造車的實(shí)現(xiàn) public class ProduceWorkShop extends WorkShop { public ProduceWorkShop() { super(); } @Override public void work(Vehicle vehicle) { System.out.print("Producing... "); } } //測(cè)試車的實(shí)現(xiàn) public class TestWorkShop extends WorkShop { public TestWorkShop() { super(); } @Override public void work(Vehicle vehicle) { System.out.print("Testing... "); } } //使用 public class Main { public static void main(String[] args) { //生產(chǎn)一輛自行車 Vehicle bike = new Bike(); bike.joinWorkshop(new ProduceWorkShop()); bike.manufacture(); //生產(chǎn)一輛汽車 Vehicle car = new Car(); car.joinWorkshop(new ProduceWorkShop()); car.joinWorkshop(new TestWorkShop()); car.manufacture(); } }
最后,單看設(shè)計(jì)模式例子是非常簡(jiǎn)單的,但有時(shí)候?qū)懘a時(shí)卻用不上這些設(shè)計(jì)模式,這是一種寫代碼思維上的轉(zhuǎn)變。也就是在寫代碼之前,我們需要根據(jù)業(yè)務(wù)場(chǎng)景思考,那種設(shè)計(jì)模式適合使用,記住使用設(shè)計(jì)模式的最終目的是代碼可讀性強(qiáng),高內(nèi)聚低耦合,可擴(kuò)展。這是一種思維上的轉(zhuǎn)變,多思考在動(dòng)手,熟能生巧。
PS:
清山綠水始于塵,博學(xué)多識(shí)貴于勤。
微信公眾號(hào):「清塵閑聊」。
歡迎一起談天說地,聊代碼。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/74913.html
摘要:提供酒店相關(guān)的接口返回該時(shí)間段有效的酒店提供航班相關(guān)的接口返回該時(shí)間段有效的航班提供一個(gè)旅行對(duì)外的接口,一次返回酒店和航班信息調(diào)用旅行外觀模式享元模式享元模式主要用于減少創(chuàng)建對(duì)象的數(shù)量,以減少內(nèi)存占用和提高性能。 組合模式(Composite pattern) 組合模式看起來就像對(duì)象組的樹形結(jié)構(gòu),一個(gè)對(duì)象里面包含一個(gè)或一組其他的對(duì)象。它是屬于結(jié)構(gòu)型模式。例如,一個(gè)公司包括很多個(gè)部門,每...
摘要:是一款基于的服務(wù)端渲染框架,跟的異曲同工。該配置項(xiàng)用于定義應(yīng)用客戶端和服務(wù)端的環(huán)境變量。 Vue因其簡(jiǎn)單易懂的API、高效的數(shù)據(jù)綁定和靈活的組件系統(tǒng),受到很多前端開發(fā)人員的青睞。國(guó)內(nèi)很多公司都在使用vue進(jìn)行項(xiàng)目開發(fā),我們正在使用的簡(jiǎn)書,便是基于Vue來構(gòu)建的。 我們知道,SPA前端渲染存在兩大痛點(diǎn):(1)SEO。搜索引擎爬蟲難以抓取客戶端渲染的頁面meta信息和其他SEO相關(guān)信息,使...
摘要:是一款基于的服務(wù)端渲染框架,跟的異曲同工。該配置項(xiàng)用于定義應(yīng)用客戶端和服務(wù)端的環(huán)境變量。 Vue因其簡(jiǎn)單易懂的API、高效的數(shù)據(jù)綁定和靈活的組件系統(tǒng),受到很多前端開發(fā)人員的青睞。國(guó)內(nèi)很多公司都在使用vue進(jìn)行項(xiàng)目開發(fā),我們正在使用的簡(jiǎn)書,便是基于Vue來構(gòu)建的。 我們知道,SPA前端渲染存在兩大痛點(diǎn):(1)SEO。搜索引擎爬蟲難以抓取客戶端渲染的頁面meta信息和其他SEO相關(guān)信息,使...
摘要:全書分三大部分共章第章介紹的基礎(chǔ)知識(shí)安裝和基本語法第章介紹的基本編程機(jī)器學(xué)習(xí)基礎(chǔ)及中常用的第三方庫(kù)函數(shù),并介紹數(shù)據(jù)預(yù)處理的基本方法第章分別介紹常用的機(jī)器學(xué)習(xí)分析算法及深度學(xué)習(xí)等。每章都采用多個(gè)經(jīng)典案例圖文并茂地介紹機(jī)器學(xué)習(xí)的原理和實(shí)現(xiàn)方法。 最近在學(xué)習(xí)Java和全棧開發(fā),推薦一些有用的書籍 書架主要針對(duì)Java后端和全棧開發(fā)用的 書籍介紹 《Spring Boot 2.0企業(yè)級(jí)應(yīng)用開發(fā)...
閱讀 2548·2021-10-08 10:17
閱讀 1900·2021-09-06 15:02
閱讀 2594·2019-08-29 17:30
閱讀 2719·2019-08-29 13:24
閱讀 1577·2019-08-29 11:12
閱讀 3407·2019-08-28 17:52
閱讀 715·2019-08-26 11:30
閱讀 3654·2019-08-26 11:01