亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

通熟易懂的設(shè)計(jì)模式(一)

luxixing / 1270人閱讀

摘要:維基百科抽象工廠的例子構(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 static  List asList(T... a) {
        return new ArrayList<>(a);
    }

在 JDK 中,Collections 工具類的 list() 方法把枚舉轉(zhuǎn)集合。

    public static  ArrayList 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 List workshops = 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è)計(jì)模式(二)

    摘要:提供酒店相關(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è)部門,每...

    daydream 評(píng)論0 收藏0
  • 淺談NUXT - 基于vue.js服務(wù)端渲染框架

    摘要:是一款基于的服務(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)信息,使...

    yearsj 評(píng)論0 收藏0
  • 淺談NUXT - 基于vue.js服務(wù)端渲染框架

    摘要:是一款基于的服務(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)信息,使...

    godiscoder 評(píng)論0 收藏0
  • Java后端學(xué)習(xí),你應(yīng)該看那些書籍?

    摘要:全書分三大部分共章第章介紹的基礎(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ā)...

    QiuyueZhong 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<