設計模式之工廠方法模式|抽象工廠模式

Code4Android發表於2017-03-07

工廠方法模式(Factory Method)

工廠方法模式(Factory Method)是一種建立型的設計模式,在該模式中父類決定例項的生成方式。但是不決定它要生成的具體的類,具體的處理是交給子類完成的,這樣將生成例項的框架和負責生成例項的類解耦。

接下來通過一個製作身份證明的IDCard來學習工廠方法模式,照例先來一張類圖,對該例程式有大概的認識。

類圖:

設計模式之工廠方法模式|抽象工廠模式
這裡寫圖片描述

產品類Product

Product屬於工廠方法模式中的"產品"類,在該類中僅僅宣告瞭一個抽象方法use(),定義了任意產品都可以use的方法,即定義了生成的例項所持有的介面方法。

public abstract class Product {
    public abstract void use();
}複製程式碼

工廠類Factory

該類是生產Product的類,該類內部提供了一個create方法建立產品,並且提供抽象方法createProduct建立產品和registerProduct註冊產品。他在工廠方法模式充當建立者這一角色,負責生成產品Product,但是具體處理交由具體建立者。對於使用生成例項的專用方法createProduct建立例項,而不用new關鍵字來生成,這樣做的好處是可以防止
父類與其他類耦合。

public abstract class Factory {
    public final Product create(String owner) {
        Product p = createProduct(owner);
        registerProduct(p);
        return p;
    }
    protected abstract Product createProduct(String owner);
    protected abstract void registerProduct(Product product);
}複製程式碼

具體產品類IDCard

在上面說到產品類Product,它需要子類去實現具體的產品IDCard,而IDCard和Product是分離的。

public class IDCard extends Product {
    private String owner;
    IDCard(String owner) {
        System.out.println("製作ID卡"+owner);
        this.owner = owner;
    }
    public void use() {
        System.out.println("使用ID卡"+owner);
    }
    public String getOwner() {
        return owner;
    }
}複製程式碼

具體工廠類IDCardFactory

IDCardFactory是工廠類Factory的具體實現,通過createProduct方法生成具體的產品,並通過registerProduct方法將有owner生成的具體產品IDCard儲存到owners實現產品註冊。

public class IDCardFactory extends Factory {
    private List owners = new ArrayList();
    protected  Product createProduct(String owner) {
        return new IDCard(owner);
    }
    protected void registerProduct(Product product) {
        IDCard card = (IDCard)product;
        owners.add(card.getOwner());
    }
    public List getOwners() {
        return owners;
    }
}複製程式碼

測試類Main

public class Main {
    public static void main(String[] args) {
        Factory factory = new IDCardFactory();
        Product card1 = factory.create("小明");
        Product card2 = factory.create("小紅");
        Product card3 = factory.create("小剛");
        card1.use();
        card2.use();
        card3.use();
    }
}複製程式碼

輸出資訊

製作ID卡小明
製作ID卡小紅
製作ID卡小剛
使用ID卡小明
使用ID卡小紅
使用ID卡小剛複製程式碼

在上面的介紹中我們的需求是生產一個IDCard,那麼如果我們生成一個電視機呢,我們只需要建立一個電視機Televison和生成電視機的具體工廠類TelevisionFactory,在此,我們不需要修改產品類Product和工廠類Factory,就可以建立我們需要的產品。

抽象工廠模式

在上面的工廠方法中具體的產品和具體的工廠是一一對應的,一個工廠只能生產一種產品,結構單一,例如小米公司剛開始是隻生產小米手機,但是伴隨著公司的發展,他們需要生產不同型號的手機,也會生產路由器,小米電視等等,那麼工廠方法模式已不能滿足業務的需求了,此時我們就需要抽象工廠模式,即一個工廠可以生產多種產品。(當然使用工廠方法也是可以的,不過需要建立多個具體工廠)
在抽象工廠模式中引入兩個重要的概念一個是產品等級結構,它是產品的繼承結構例如一個抽象產品電視類它的子類可以為各種型號或的電視。那麼產品族是什麼呢?在上面提到小米可以生產手機,電視,路由器等,那麼這些就是一個產品族。

在圖解設計模式一書中,是通過將帶有層次結構關係的集合標籤製成HTML檔案的示例講解抽象工廠模式的,不過我感覺示例程式碼稍微有點多,所以基於自己的理解,通過開始所說的小米生產手機和電視的這個例子來總結抽象工廠模式。

照例先看類圖:

設計模式之工廠方法模式|抽象工廠模式
這裡寫圖片描述

抽象產品

抽象產品角色負責定義抽象工廠生成的產品的介面,在本例中有兩個抽象產品類,分別是手機和電視的抽象類,對應有一個打電話dial()和watchTV()方法

public abstract class IMobilePhone {
    public abstract void dial();
}
public abstract class ITelevision {
    public abstract void watchTV();
}複製程式碼

具體產品類

具體產品角色負責實現抽象產品角色的介面。

public class MobilePhone extends IMobilePhone {
    private String name;
    public MobilePhone(String name) {
        this.name=name;
        System.out.println("製作手機"+name);
    }

    @Override
    public void dial() {
        System.out.println("使用"+name+"打電話");
    }
}


public class Television extends ITelevision {
    private String name;
    public Television(String name) {
        this.name=name;
        System.out.println("製作電視"+name);
    }

    @Override
    public void watchTV() {
        System.out.println("通過"+name+"看電視");
    }
}複製程式碼

抽象工廠類

抽象工廠角色是負責定義用於生成抽象產品的介面。

public abstract class Factory {
    public static Factory getFactory(String classname) {
        Factory factory = null;
        try {
            factory = (Factory)Class.forName(classname).newInstance();
        } catch (ClassNotFoundException e) {
            System.err.println("沒有找到 " + classname + "類。");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return factory;
    }
    public abstract MobilePhone createMobilePhone(String type);
    public abstract Television createTelevision(String type);
}複製程式碼

具體工廠

實現抽象工廠的抽象方法生成產品。

public class XiaoMiFactory extends  Factory{
    @Override
    public MobilePhone createMobilePhone(String type) {
        return new MobilePhone(type);
    }
    @Override
    public Television createTelevision(String type) {
        return new Television(type);
    }
}複製程式碼

測試類

public class Main {
    public static void main(String[] args) {
        Factory factory = Factory.getFactory("com.abstractfactory.XiaoMiFactory");
        IMobilePhone mobilePhone1=factory.createMobilePhone("小米2");
        IMobilePhone mobilePhone2=factory.createMobilePhone("小米5");

        ITelevision television1=factory.createTelevision("小米電視2");
        ITelevision television2=factory.createTelevision("小米電視3");

        mobilePhone1.dial();
        mobilePhone2.dial();

        television1.watchTV();
        television2.watchTV();

    }
}複製程式碼

輸出資訊

製作手機小米2
製作手機小米5
製作電視小米電視2
製作電視小米電視3
使用小米2打電話
使用小米5打電話
通過小米電視2看電視
通過小米電視3看電視複製程式碼

兩者關係分析

對於工廠方法它是通過類繼承建立抽象產品,並且是建立一種產品,如果建立新的產品,只需新建一個工廠過載工廠方法以建立新的產品。

在抽象工廠模式中,它實現了具體類生成的分離,因此增加具體工廠變的很簡單,例如現在華為也生產手機和電視,我們只需要建立具體的工廠類就可以了。對於工廠類抽象工廠模式是很容易增加的,但是如果小米公司現在業務又擴充了,開始做機器人,這樣就困難了,我們需要將所有的工廠做修改,新增建立機器人的方法,如果之前工廠類很多,那麼這個工作量就會很大了。

總而言之,這兩種都是工廠模式,形式上很相似,最終的目的都是為了解耦,實現低耦合。而且它們之間很容易互相轉換,當我們使用工廠模式後可能加了一個方法就成為了抽象工廠模式。不管你如何使用,只有達到我們程式碼低耦合,清晰明瞭的目的就可以。當然這是個人感覺。

好了,自己關於工廠模式的理解到這裡已經總結完畢了。有問題歡迎留言指出,Have a wonderful day .

如需文章中所寫程式碼,請移步GitHub檢視

相關文章