設計模式六大原則之工廠方法模式與抽象工廠模式


  前言:不斷學習就是程序員的宿命

一、概述

案例需求:一個手機的項目:要便於手機種類的擴展,便於維護

  (1)手機的種類很多(比如華為、小米、oppo等)

  (2)手機的制作(prepare,produce,box)

  (3)完成手機店訂購的功能

二、傳統模式

public class OrderPhone {
    // 構造器
    public OrderPhone() {
        Phone phone = null;
        String orderType; // 訂購手機的類型
        do {
            orderType = getType();
            if (orderType.equals("xiaomi")) {
                phone = new XiaomiPhone();
                phone.setName(" 小米手機 ");
            } else if (orderType.equals("huawei")) {
                phone = new HuaweiPhone();
                phone.setName(" 華為手機 ");
            } else if (orderType.equals("pepper")) {
                phone = new OppoPhone();
                phone.setName("oppo手機");
            } else {
                break;
            }
            //輸出pizza 制作過程
            phone.prepare();
            phone.produce();
            phone.box();

        } while (true);
    }
    // 寫一個方法,可以獲取客戶希望訂購的手機種類
    private String getType() {
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input 手機 種類:");
            String str = strin.readLine();
            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
}
傳統方式

分析:

  (1)優點:容易理解,簡單易操作

  (2)缺點:違反了設計模式的OCP原則(對擴展開放,對修改關閉)當我們給類增加新功能的時候,盡量不修改代碼或者盡可能少修改代碼

  (3)例如此時要新增加一個手機種類(榮耀手機)則需要新增一個手機類,而且只要是訂購手機的代碼都要修改

三、簡單工廠模式(違反OCP)

①簡單工廠模式屬於創建型模式,是工廠模式的一種。簡單工廠模式是由一個工廠對象決定創建出哪一種產品類的實例。簡單工廠模式是工廠模式家族中最簡單使用的模式。

②簡單工廠模式:定義了一個創建對象的類,由這個類來封裝實例化對象的行為

③在軟件開發中,當我們會用到大量的創建某種、某類或某批對象時,就會使用到工廠模式。

  改進:基於傳統模式修改,把創建Phone對象封裝到一個類中,這樣有新的手機類時只需要修改該類即可,其他有創建到Phone對象的代碼就不用修改了,改進后的uml類圖

public class SimpleFactory {
    //簡單工廠模式 也叫 靜態工廠模式

    public static Phone createPhone(String orderType) {

        Phone phone = null;

        System.out.println("使用簡單工廠模式");
        if (orderType.equals("xiaomi")) {
            phone = new XiaomiPhone();
            phone.setName(" 小米手機 ");
        } else if (orderType.equals("huawei")) {
            phone = new HuaweiPhone();
            phone.setName(" 華為手機 ");
        } else if (orderType.equals("pepper")) {
            phone = new OppoPhone();
            phone.setName("oppo手機");
        }

        return phone;
    }
}
View Code

三、工廠方法模式 

1、工廠方法模式4要素

  ①抽象工廠(Abstract Factory):提供了創建產品的接口,調用者通過它訪問具體工廠的工廠方法new Product()來創建產品。

  ②具體工廠(ConcreteFactory):主要是實現抽象工廠中的抽象方法,完成具體產品的創建。

  ③抽象產品(Product):定義了產品的規范,描述了產品的主要特性和功能。

  ④具體產品(ConcreteProduct):實現了抽象產品角色所定義的接口,由具體工廠來創建,它同具體工廠之間一一對應。

2、新需求

  客戶在訂購手機時,可以選擇不同顏色的手機,比如小米夢幻藍Phone、小米曜石黑Phone或者華為零度白Phone、華為亮黑色Phone。

  思路1:使用工廠模式,創建不同的簡單工廠類,比如XMBlueSimpleFactory、HWBlackSimpleFactory等,這樣考慮是可以的,但是考慮到項目的規模,以及軟件的可維護性、可擴展性並不是特別好。

  思路2:使用工廠方法模式

  工廠方法模式介紹:定義了一個創建對象的抽象方法,由子類決定要實例化的類。工廠方法模式將對象的實例化推遲到子類(核心)

  基於工廠方法模式設計方案:將手機實例化功能抽象成抽象方法,在不同顏色的訂購子類中具體實現。

 

分析:

  (1)優點

    ①用戶只需要知道具體工廠的名稱就可得到所要的產品,無須知道產品的具體創建過程;

    ②在系統增加新的產品時只需要添加具體產品類和對應的具體工廠類,無須對原工廠進行任何修改,滿足開閉原則;

  (2)缺點:每增加一個產品就要增加一個具體產品類和一個對應的具體工廠類,這增加了系統的復雜度。

3、適用場景

(1)客戶只知道創建產品的工廠名,而不知道具體的產品名。如 TCL 電視工廠、海信電視工廠等。

(2)創建對象的任務由多個具體子工廠中的某一個完成,而抽象工廠只提供創建產品的接口。

(3)客戶不關心創建產品的細節,只關心產品的品牌。

四、抽象工廠模式

1、簡介

  抽象工廠模式:定義了一個interface用於創建相關或有依賴關系的對象簇,而無需指明具體的類。抽象工廠模式可以將簡單工廠模式和工廠方法模式進行整合;從設計層面來看,抽象工廠模式就是對簡單工廠模式的改進(或者進一步的抽象);將工廠抽象成兩層,AbstractFactory(抽象工廠)和具體實現的工廠子類。程序員可以根據創建對象類型使用對應的工廠子類。這樣將單個的簡單工廠類變成了工廠簇,更利於代碼的維護和擴展。

2、模式結構

①抽象工廠(Abstract Factory):提供了創建產品的接口,它包含多個創建產品的方法 newProduct(),可以創建多個不同等級的產品。

②具體工廠(Concrete Factory):主要是實現抽象工廠中的多個抽象方法,完成具體產品的創建。

③抽象產品(Product):定義了產品的規范,描述了產品的主要特性和功能,抽象工廠模式有多個抽象產品。

④具體產品(ConcreteProduct):實現了抽象產品角色所定義的接口,由具體工廠來創建,它 同具體工廠之間是多對一的關系。

3、本例UML類圖

 分析:

  (1)當增加一個新的產品族(Oppo手機類)時只需增加一個新的具體工廠(Oppo工廠),不需要修改原代碼,滿足開閉原則

  (2)當產品族中需要增加一個新種類(抽象工廠新增生產空調產品)的產品時,則所有的工廠類(各個具體工廠例如華為、小米工廠類等都要修改)都需要進行修改,不滿足開閉原則

 4、適用場景

(1)當需要創建的對象是一系列相互關聯或相互依賴的產品族時,如電器工廠中的電視機、洗衣機、空調等。

(2)系統中有多個產品族,但每次只使用其中的某一族產品。如有人只喜歡穿某一個品牌的衣服和鞋。

(3)系統中提供了產品的類庫,且所有產品的接口相同,客戶端不依賴產品實例的創建細節和內部結構。

五、工廠模式在JDK源碼中的應用

 六、總結

1、工廠模式的意義:將實例化對象的代碼提取出來,放到一個類中統一管理維護,達到和主項目依賴關系的管理,從而提高項目的擴展和維護性。

2、設計模式的依賴抽象原則:

  ①創建對象實例時,不要直接new類,而是把這個new類的動作放在一個工廠的方法中並返回(變量不要直接持有具體類的引用)

  ②不要讓類繼承具體類,而是繼承抽象類或是實現Interface接口

  ③不要覆蓋基類中已實現的方法

 參考:http://c.biancheng.net/view/1351.html(如有侵權,請聯系刪除)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM