應用最廣泛的模式——工廠方法模式

HunterArley發表於2019-01-24

《Android原始碼設計模式解析與實戰》讀書筆記(五) 《Android原始碼設計模式解析與實戰》PDF資料下載

一、工廠方法模式簡介

工廠方法模式,是建立型設計模式之一。

1.1、定義

定義一個用於建立物件的介面,讓子類決定例項化哪個類。

1.2、使用場景

在任何需要生成複雜物件的地方,都可以使用工廠方法模式。複雜物件適合使用工廠模式,用new就可以完成建立的物件無需使用工廠模式。

二、工廠方法模式的簡單實現

public abstract class AudiFactory {
    public abstract <T extends AudiCar> T createAudiCar(Class<T> clz);
}
複製程式碼
public class AudiCarFactory extends AudiFactory {
    @Override
    public <T extends AudiCar> T createAudiCar(Class<T> clz) {
        AudiCar car = null;
        try {
            car = (AudiCar) Class.forName(clz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T)car;
    }
}
複製程式碼
public abstract class AudiCar {
    /**
     * 汽車的抽象產品類
     * <p>
     * 定義汽車的一個行為方法,車可以啟動開走
     */
    public abstract void drive();

    /**
     * 定義汽車的一個行為方法,車可以自動巡航
     */
    public abstract void selfNavigation();
}
複製程式碼
public class AudiQ3 extends AudiCar {
    @Override
    public void drive() {
        System.out.println("Q3啟動了!");
    }

    @Override
    public void selfNavigation() {
        System.out.println("Q3開始自動巡航!");
    }
}
複製程式碼
public class AudiQ5 extends AudiCar {
    @Override
    public void drive() {
        System.out.println("Q5啟動了!");
    }

    @Override
    public void selfNavigation() {
        System.out.println("Q5開始自動巡航!");
    }
}
複製程式碼
public class AudiQ7 extends AudiCar {
    @Override
    public void drive() {
        System.out.println("Q7啟動了!");
    }

    @Override
    public void selfNavigation() {
        System.out.println("Q7開始自動巡航!");
    }
}
複製程式碼
//構造一個製造汽車的工廠物件
AudiFactory factory = new AudiCarFactory();

//生產Q3並啟動
AudiQ3 audiQ3 = factory.createAudiCar(AudiQ3.class);
audiQ3.drive();
audiQ3.selfNavigation();

//生產Q5並啟動
AudiQ5 audiQ5 = factory.createAudiCar(AudiQ5.class);
audiQ5.drive();
audiQ5.selfNavigation();

//生產Q7並啟動
AudiQ7 audiQ7 = factory.createAudiCar(AudiQ7.class);
audiQ7.drive();
audiQ7.selfNavigation();
複製程式碼

輸出結果:

工廠模式.png

三、工廠方法模式實戰

以資料儲存為例,程式碼如下所示:

public abstract class IOHandler {
    /**
     * 新增一條個人資訊
     * @param id
     * @param name
     */
    public abstract void add(String id, String name);

    /**
     * 刪除一條個人資訊
     * @param id
     */
    public abstract void remove(String id);

    /**
     * 更新一條個人資訊
     * @param id
     * @param name
     */
    public abstract void update(String id, String name);

    /**
     * 查詢身份證對應的人名
     * @param id
     * @return
     */
    public abstract String query(String id);
}
複製程式碼

對每一種持久化方式都定義一個具體的IO處理類,分別為普通檔案儲存、xml檔案儲存和SQLite資料庫儲存。

public class FileHandler extends IOHandler {
    @Override
    public void add(String id, String name) {

    }

    @Override
    public void remove(String id) {

    }

    @Override
    public void update(String id, String name) {

    }

    @Override
    public String query(String id) {
        return "AigeStudio";
    }
}
複製程式碼
public class XMLHandler extends IOHandler {
    @Override
    public void add(String id, String name) {

    }

    @Override
    public void remove(String id) {

    }

    @Override
    public void update(String id, String name) {

    }

    @Override
    public String query(String id) {
        return "SMBrother";
    }
}
複製程式碼
public class DBHandler extends IOHandler {
    @Override
    public void add(String id, String name) {

    }

    @Override
    public void remove(String id) {

    }

    @Override
    public void update(String id, String name) {

    }

    @Override
    public String query(String id) {
        return "Android";
    }
}
複製程式碼

定義一個工廠類,如下:

public class IOFactory {
    public static <T extends IOHandler> T getIOHandler(Class<T> clz) {
        IOHandler handler = null;
        try {
            handler = (IOHandler) Class.forName(clz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) handler;
    }
}
複製程式碼

四、總結

4.1、優點

  1. 在工廠方法模式中,工廠方法用來建立客戶所需要的產品,同時還向客戶隱藏了哪種具體產品類將被例項化這一細節,使用者只需要關心所需產品對應的工廠,無須關心建立細節,甚至無須知道具體產品類的類名。
  2. 基於工廠角色和產品角色的多型性設計師工廠方法模式的關鍵。它能夠使工廠可以自主確定建立何種產品物件,而如何建立這個物件的細節則完全封裝在具體工廠內部。工廠方法模式之所以又被稱為多型工廠模式,是因為所有的具體工廠類都具有同一抽象父類。
  3. 使用工廠方法模式的另一個優點是在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的介面,無須修改客戶端,也無需修改其他的具體工廠和具體產品,而只要新增一個具體工廠和具體產品就可以了。這樣,系統的可擴充套件性也變得更好,符合“開閉原則。

4.2、缺點

  1. 在新增新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,系統中類的個數將成對增加,在一定程度上增加了系統的複雜度,有更多的類需要編譯和執行,會給系統帶來一些額外的開銷。
  2. 由於考慮到系統的可擴充套件性,需要引入抽象層,在客戶端程式碼中均使用抽象層進行定義,增加了系統的抽象性和理解難度,且在實現時可能需要用到DOM、反射等技術,增加了系統的實現難度。

學海無涯苦作舟

我的微信公眾號

相關文章