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

工廠方法模式(Factory Method)

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

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

類圖:git

這裏寫圖片描述

產品類Product

Product屬於工廠方法模式中的"產品"類,在該類中僅僅聲明瞭一個抽象方法use(),定義了任意產品均可以use的方法,即定義了生成的實例所持有的接口方法。github

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實現產品註冊。ide

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,就能夠建立咱們須要的產品。測試

抽象工廠模式

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

在圖解設計模式一書中,是經過將帶有層次結構關係的集合標籤製成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查看

相關文章
相關標籤/搜索