国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

通熟易懂的設計模式(一)

luxixing / 1205人閱讀

摘要:維基百科抽象工廠的例子構建模式當構建一個復雜對象時,就可以使用建造者模式。在中,類中的方法就是適配器模式的例子,把一個數組轉換為一個集合。這種設計模式的好處是方便添加一種車巴士,只需要繼承類。

寫在前面

評判一個程序員是否優秀,就是 show me the code。優秀的代碼可讀性強,高內聚低耦合,可擴展。想要寫優秀的代碼,做個優秀的程序員,就需要多看看大牛寫的開源框架,吸取其中的精華,多學學設計模式,除此之外,沒有任何其他捷徑。

設計模式主要分為創建型模式結構型模式行為型模式三種類型。

工廠方法(Factory method pattern)

定義一個創建對象的接口,讓實現這個接口的類來決定實例化哪個類。工廠方法讓類的實例化推遲到子類中進行,它屬于創建型模式。

工廠對象通常包含一個或多個方法,用來創建這個工廠所能創建的各種類型的對象。這些方法可能接收參數,用來指定對象創建的方式,最后返回創建的對象。

工廠通常是一個用來創建其他對象的對象。工廠是構造方法的抽象,用來實現不同的分配方案。

維基百科工廠方法的例子

// 定義了 Button 如何創建
public interface Button{}
// 實現了 WinButton 
public class WinButton implements Button{}
// 實現了 MacButton 
public class MacButton implements Button{}

// 創建 Button 的工廠類
public interface ButtonFactory {
    Button createButton();
}
// 真正創建 WinButton 的實現類,實現了 ButtonFactory
public class WinButtonFactory implements ButtonFactory {
    @Override
    public static Button createButton(){
        return new WinButton();
    }
}
// 真正創建 MacButton的實現類,實現了 ButtonFactory
public class MacButtonFactory implements ButtonFactory {
    @Override
    public static Button createButton(){
        return new MacButton();
    }
}
抽象工廠模式(Abstract factory pattern)

將一組具有同一主題的多帶帶的工廠封裝起來。在使用中,使用方需要創建抽象工廠的具體實現,然后使用抽象工廠作為接口來創建這一方法的具體對象。它屬于創建型模式。

抽象工廠就好像是對工廠方法的一種擴展,有個產品族的概念,也就是一堆產品。上面的工廠方法就一個產品(Button),而下面抽象工廠的例子里有兩個產品(Button和 Border)。

抽象工廠的優點:
具體產品從客戶代碼中被分離出來。
容易改變產品的系列。
將一個系列的產品族統一到一起創建。

抽象工廠的缺點:
在產品族中擴展新的產品是很困難的,它需要修改抽象工廠的接口。

維基百科抽象工廠的例子

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();
    }
}
構建模式(Builder pattern)

當構建一個復雜對象時,就可以使用建造者模式。它實際上就是傳入一個參數,然后返回對象本身,方便下一個屬性或者參數來構建。可以按需構建對象,可擴展性強。它屬于創建型模式。

在 JDK 中,StringBuilder 類的 append() 方法就是一個很好的構建模式例子。

    // java.lang.StringBuilder
    @Override
    public StringBuilder append(CharSequence s) {
        super.append(s);
        return this;
    }
原型模式(Prototype pattern)

它的特點在于通過 復制 一個已經存在的實例來返回新的實例,而不是新建實例。被復制的實例就是我們所稱的原型,這個原型是可定制的。它屬于創建型模式。

原型模式多用于創建復雜的或者耗時的實例,因為這種情況下,復制一個已經存在的實例使程序運行更高效,它們實際上就是命名不一樣的同類數據。

在 JDK 中,Object 類中的 clone() 方法就是典型的原型模式。

    //在具體的實現類里可以直接重寫 clone() 方法
    protected native Object clone() throws CloneNotSupportedException;
單例模式(Singleton pattern)

不管在任何時候,獲取一個對象時只會返回同一個實例。通常我們在都讀取配置文件時,文件里的內容是不變的,因此我們就可以使用單例模式來實現。它屬于創建型模式。

單例模式很簡單,只需要三步就完成,下面是 JDK 里的 Runtime 類實現的單例模式。

public class Runtime {
    // 1.new 一個私有的靜態的 Runtime 實例
    private static Runtime currentRuntime = new Runtime();

    // 2.返回當前應用的 Runtime 實例
    public static Runtime getRuntime() {
        return currentRuntime;
    }

    // 3.私有化構造方法,不允許在其它類構造 Runtime 實例
    private Runtime() {}
}
適配器模式(Adapter pattern)

適配器模式也稱作包裝(wrapper),它屬于結構型模式。

它的作用是把原本兩個不兼容的接口通過一個適配器或者包裝成兼容的接口,然后它們可以一起工作。例如我們的手機數據線,就好比是一個適配器,一端是 USB接口,一端是 Type-C 或者 Lightning 接口,本來它們是不能一起工作的,但我們用這跟數據線(適配器)就可以讓它們協同工作了。

它的優點:
1.可以讓任何兩個沒有關聯的接口一起工作。
2.提高了接口的復用。
3.增加了接口的透明度。
4.靈活性好。

它的缺點:
1.過多地使用適配器,會讓系統非常零亂,不易整體進行把握。
2.由于 JAVA 只能繼承一個類,所以最多只能適配一個適配者類,而且目標類必須是抽象類。

在 JDK 中,Arrays 類中的 asList(T... a) 方法就是適配器模式的例子,把一個數組轉換為一個集合。

    public static  List asList(T... a) {
        return new ArrayList<>(a);
    }

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

    public static  ArrayList list(Enumeration e) {
        ArrayList l = new ArrayList<>();
        while (e.hasMoreElements())
            l.add(e.nextElement());
        return l;
    }

當然,這上面兩個例子是非常簡單的,好像看不出來使用了任何的設計模式,跟我們平時使用的轉換一模一樣。這里只是一個理念的介紹,實際上,在使用中是用一個中間的 Adapter 類來做兼容或者包裝的。

橋接模式(Bridge pattern)

將抽象與其實現分離,以便兩者可以獨立變化。它屬于結構型模式。

當一個類經常變化時,面向對象編程的特性變得非常有用,因為可以用最少的關于程序的先驗知識來容易地改變程序的代碼。當類和它經常變化時,橋模式很有用。類本身可以被認為是抽象,類可以作為實現來做。橋模式也可以被認為是兩層抽象。

它通過提供抽象化和實現化之間的橋接結構,來實現二者的解耦。

它的優點:
1.抽象和實現分離開。
2.優秀的擴展能力。
3.實現細節對調用方透明。

它的缺點:
橋接模式的引入會增加系統的理解與設計難度,由于聚合關聯關系建立在抽象層,需要針對抽象進行設計與編程,加深編程難度。

這是個生產不同車輛和需要不同生產流程的例子。首先,定義一個車輛(Vehicle)的抽象接口,里面有個生產車輛的對應流程集合和一個生產的抽象方法。然后是自行車(Bike)和汽車(Car)對抽象接口的實現。然后定義一個生產車輛需要的流程(WorkShop),它有兩個實現 ProduceWorkShop 和 TestWorkShop。最后,main 方法的代碼就是對這個橋接模式的使用方式。

這種設計模式的好處是方便添加一種車巴士(Bus),只需要繼承 Vehicle 類。也非常方便的添加一種生產流程噴漆(PaintWorkShop),只需要繼承 WorkShop 類即可,擴展性很高。

//車輛的抽象接口
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();
}

//自行車的實現
public class Bike extends Vehicle {
    @Override
    public void manufacture() {
        System.out.println("Manufactoring Bike...");
        workshops.stream().forEach(workshop -> workshop.work(this));
    }
}
//汽車的實現
public class Car extends Vehicle {
    @Override
    public void manufacture() {
        System.out.println("Manufactoring Car");
        workshops.stream().forEach(workshop -> workshop.work(this));
    }
}
//生產車的抽象接口
public abstract class WorkShop {
    public abstract void work(Vehicle vehicle);
}
//制造車的實現
public class ProduceWorkShop extends WorkShop {
    public ProduceWorkShop() {
        super();
    }
    @Override
    public void work(Vehicle vehicle) {
        System.out.print("Producing... ");
    }
}
//測試車的實現
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) {
        //生產一輛自行車
        Vehicle bike = new Bike();
        bike.joinWorkshop(new ProduceWorkShop());
        bike.manufacture();
        //生產一輛汽車
        Vehicle car = new Car();
        car.joinWorkshop(new ProduceWorkShop());
        car.joinWorkshop(new TestWorkShop());
        car.manufacture();
    }
}

最后,單看設計模式例子是非常簡單的,但有時候寫代碼時卻用不上這些設計模式,這是一種寫代碼思維上的轉變。也就是在寫代碼之前,我們需要根據業務場景思考,那種設計模式適合使用,記住使用設計模式的最終目的是代碼可讀性強,高內聚低耦合,可擴展。這是一種思維上的轉變,多思考在動手,熟能生巧。

PS:
清山綠水始于塵,博學多識貴于勤。
微信公眾號:「清塵閑聊」。
歡迎一起談天說地,聊代碼。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/74913.html

相關文章

  • 通熟易懂設計模式(二)

    摘要:提供酒店相關的接口返回該時間段有效的酒店提供航班相關的接口返回該時間段有效的航班提供一個旅行對外的接口,一次返回酒店和航班信息調用旅行外觀模式享元模式享元模式主要用于減少創建對象的數量,以減少內存占用和提高性能。 組合模式(Composite pattern) 組合模式看起來就像對象組的樹形結構,一個對象里面包含一個或一組其他的對象。它是屬于結構型模式。例如,一個公司包括很多個部門,每...

    daydream 評論0 收藏0
  • 淺談NUXT - 基于vue.js服務端渲染框架

    摘要:是一款基于的服務端渲染框架,跟的異曲同工。該配置項用于定義應用客戶端和服務端的環境變量。 Vue因其簡單易懂的API、高效的數據綁定和靈活的組件系統,受到很多前端開發人員的青睞。國內很多公司都在使用vue進行項目開發,我們正在使用的簡書,便是基于Vue來構建的。 我們知道,SPA前端渲染存在兩大痛點:(1)SEO。搜索引擎爬蟲難以抓取客戶端渲染的頁面meta信息和其他SEO相關信息,使...

    yearsj 評論0 收藏0
  • 淺談NUXT - 基于vue.js服務端渲染框架

    摘要:是一款基于的服務端渲染框架,跟的異曲同工。該配置項用于定義應用客戶端和服務端的環境變量。 Vue因其簡單易懂的API、高效的數據綁定和靈活的組件系統,受到很多前端開發人員的青睞。國內很多公司都在使用vue進行項目開發,我們正在使用的簡書,便是基于Vue來構建的。 我們知道,SPA前端渲染存在兩大痛點:(1)SEO。搜索引擎爬蟲難以抓取客戶端渲染的頁面meta信息和其他SEO相關信息,使...

    godiscoder 評論0 收藏0
  • Java后端學習,你應該看那些書籍?

    摘要:全書分三大部分共章第章介紹的基礎知識安裝和基本語法第章介紹的基本編程機器學習基礎及中常用的第三方庫函數,并介紹數據預處理的基本方法第章分別介紹常用的機器學習分析算法及深度學習等。每章都采用多個經典案例圖文并茂地介紹機器學習的原理和實現方法。 最近在學習Java和全棧開發,推薦一些有用的書籍 書架主要針對Java后端和全棧開發用的 書籍介紹 《Spring Boot 2.0企業級應用開發...

    QiuyueZhong 評論0 收藏0

發表評論

0條評論

luxixing

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<