Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 工廠模式,三種工廠模式的理解

Android 工廠模式,三種工廠模式的理解

編輯:關於Android編程

工廠模式是一種創建者模式,在任何生成復雜對象的地方都可以使用工廠模式。理論來說在任何使用A a = new A()的方式都可以使用工廠模式,雖然使用工廠模式可能需要多做一些工作,但是在後續的開發和維護都帶來了方便。

如果我們需要在構建對象的時候,需要做很多的處理工作,比如初始化工作,查詢工作等一些耗時的工作,如果我們將這些操作全部放入到構造方法中去寫,那麼勢必在後期維護的帶來不方便,而且始化工作如果是很長一段代碼,說明要做的工作很多,將很多工作裝入一個方法中,相當於將很多雞蛋放在一個籃子裡,是很危險的,這也是有悖於Java面向對象的原則,面向對象的封裝(Encapsulation)和分派(Delegation)告訴我們,盡量將長的代碼分派“切割”成每段,將每段再“封裝”起來(減少段和段之間耦合聯系性),這樣,就會將風險分散,以後如果需要修改,只要更改每段,不會再發生牽一動百的事情。

工廠模式分類

簡單工廠模式 工廠模式

抽象工廠模式

三者之間的區別:

工廠方法模式只有一個抽象產品類,而抽象工廠模式有多個。 工廠方法模式的具體工廠類只能創建一個具體產品類的實例,而抽象工廠模式可以創建多個。 簡單工廠模式只有一個抽象產品類,一個工廠類

簡單工廠模式

簡單工廠模式,一個具體工廠類負責生產所有的具體產品。客戶端只需要關注生成的具體產品。

簡單工廠模式的uml圖

 

這裡寫圖片描述

 

- Factory : 負責生產具體的產品工廠

- Product: 抽象的產品類,

- P1: 具體的產品類P1

- P2: 具體的產品類P2

舉個例子。

汽車工廠造汽車的例子。首先Rrtoyewx在大眾廠裡面上班,一開始被分配到了上海大眾裡面去了,只管Passat和polo兩款車型,而且做的事很簡單,就是簡單開出去測試一下車子的性能。這個時候事務較少,Rrtoyewx覺得用簡單工廠就能搞定了。

package圖如下:

 

這裡寫圖片描述

 

- Volkswagen:抽象的大眾汽車類

- Passat,Polo:具體的大眾汽車類

- ShangHaiVolkswagenFactory: 上海大眾汽車工廠

- Client: 客戶端類

具體的代碼:

產品類
Volkswagen

public interface Volkswagen {
    void drive();

    String getName();
}

Passat

public class Passat implements Volkswagen {
    public static final int ID = 0;

    @Override
    public void drive() {
        System.out.println("Passat開出去咯,測試成功");  
    }

    @Override
    public String getName() {
        return "Passat";
    }
}

Polo

public class Polo implements Volkswagen{
    public static final int ID = 1;

    @Override
    public void drive() {
        System.out.println("Polo開出去咯,測試成功");
    }

    @Override
    public String getName() {
        return "Polo";
    }
}

工廠類

public class ShangHaiVolkswagenFactory {

    public Volkswagen createVolkswagen(int id){
        Volkswagen volkswagen = null;
        switch(id){
            case Passat.ID:
                volkswagen = new Passat();
                break;
            case Polo.ID:
                volkswagen = new Polo();
                break;
            default:
                volkswagen = null;
        }
        return volkswagen;
    }
}

客戶端類

public class Client {
    public static void main(String[] args) {
        ShangHaiVolkswagenFactory factory = new ShangHaiVolkswagenFactory();

        Volkswagen passat = factory.createVolkswagen(Passat.ID);
        passat.drive();

        Volkswagen polo = factory.createVolkswagen(Polo.ID);
        System.out.println(polo.getName());
    }
}

打印出的log為
這裡寫圖片描述

每次測試的時候Client類都跑了一遍,似乎很簡單,同樣的也方便以後的擴展(添加新的車型的時候),只需要添加一個產品類,然後在工廠裡添加響應的邏輯就行了。Rrtoyewx覺得自己這個測試車輛程序完全夠用了。

注意對於上面的工廠,可以采用反射的形式去創建產品類,如下面的代碼<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;"> public class ShangHaiVolkswagenFactory { //產品的id public Volkswagen createVolkswagen(int id){ Volkswagen volkswagen = null; switch(id){ case Passat.ID: volkswagen = new Passat(); break; case Polo.ID: volkswagen = new Polo(); break; default: volkswagen = null; } return volkswagen; } //反射得到 public Volkswagen createVolkswagen(Class clazz){ Volkswagen volkswagen = null; try { volkswagen = clazz.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return volkswagen; } }

簡單工廠模式優缺點

優點:客戶端需要的什麼產品,可以直接得到,邏輯判斷在工廠裡面,
缺點:擴展性一般,產品都是一個產品族下面的產品,對於不在產品族中的產品,沒辦法去擴展,另外獲得具體某種產品的邏輯放在工廠裡面,新添加產品的時候就需要修改工廠裡面的代碼。

工廠模式

一個抽象產品,派生出去多種具體的產品的, 一個抽象工廠,派生出多種生產產品的工廠類 一個具體的工廠負責生產一種具體的產品

工廠模式的uml圖

這裡寫圖片描述
- AbstractProduct:抽象的產品類
- ProductA:具體的A產品
- ProductB:具體的B產品
- AbstractFactory:抽象工廠類
- FactoryA:具體的生產A產品的工廠類
- FactoryB:具體的生產B產品的工廠類
- Client: 客戶端類

舉個栗子

還是上面的栗子的。Rrtoyewx在負責上海大眾的兩款車型,本來就著簡單工廠的模式測試車輛的時候,日子過的非常好,可是好景不長,突然有一天領導說Rrtoyewx說:一汽大眾廠最近較忙,看你比較清閒,你就順便把一汽大眾的邁騰,和速騰都測一下。本來Rrtoyewx覺得挺簡單的,就是簡單再添加一個Magotan和Sagitar,然後通過工廠生成就行了,可是等Rrtoyewx一拿到測試的項目的時候,發現並不是只測試drive,Sagitar和Magotan不僅需要測試drive,而且需要測試brake。好吧,Rrtoyewx覺得以前寫的都不能夠用了。想了很久,Rrtoyewx 覺得需要將簡單工廠模式升級到工廠模式,關注點也發生了改變不再為具體的車輛的,而是一汽大眾的車(Magotan和Sagitar)還是上海大眾的車(Passat和 Polo)了

修改過後的package圖:
這裡寫圖片描述
- Volkswagen: 抽象的汽車類
- ShangHaiVolkswagen:上海大眾汽車的抽象類
- FAWVolkswagen:一汽大眾汽車的抽象類
- Passat,Polo:上海大眾廠汽車類的具體類
- Magotan,Sagitar:一汽大眾廠汽車的具體類
- VolkswagenFactory:抽象的大眾汽車工廠
- ShangHaiVolkswagenFactory:上海大眾汽車工廠,主要負責測試Passat和Polo
- FAWVolkswagenFactory:一汽大眾的工廠,主要負責測試Magotan和Sagitar

具體的代碼和介紹

抽象類

產品類

Volkswagen類,將Volkswagen類轉成抽象類

public abstract class Volkswagen {
    public abstract void drive();

    public abstract String getName();

}

ShangHaiVolkswagen:上海大眾汽車的抽象類

public abstract class ShangHaiVolkswagen implements Volkswagen{

}

FAWVolkswagen : 一汽大眾汽車的抽象類,多了一個brake()的方法

public abstract class FAWVolkswagen implements Volkswagen {
    public abstract void brake();
}
工廠類

VolkswagenFactory : 汽車工廠的抽象類,並將createVolkswagen(Class clazz)聲明稱final類型。供子類使用

public abstract class VolkswagenFactory {

    public abstract Volkswagen createVolkswagen(int productID);

    public final Volkswagen createVolkswagen(Class  clazz){
        Volkswagen volkswagen = null;
        try {
            volkswagen = clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return volkswagen;
    };
}

實現類:

產品類

上海大眾的具體實現類
Passat類

public class Passat extends ShangHaiVolkswagen {
    public static final int ID = 0;

    @Override
    public void drive() {
        System.out.println("Passat開出去咯,測試成功");  
    }

    @Override
    public String getName() {
        return "Passat";
    }
}

Polo類

public class Polo extends ShangHaiVolkswagen{
    public static final int ID = 1;

    @Override
    public void drive() {
        System.out.println("Polo開出去咯,測試成功");
    }

    @Override
    public String getName() {
        return "Polo";
    }
}

一汽大眾的汽車類。
Sagitar類,

public class Sagitar extends FAWVolkswagen {
    public static final int ID = 2;

    @Override
    public void drive() {
        System.out.println("Sagitar 開出去了,測試成功了");
    }

    @Override
    public String getName() {
        return "Sagitar";
    }

    @Override
    public void brake(){
        System.out.println("Sagitar 剎車挺好的,測試通過了");
    }
}

Magotan 類

public class Magotan extends FAWVolkswagen{
    public static final int ID = 3;

    @Override
    public void drive() {
        System.out.println("Magotan 開出去咯,測試成功了");
    }

    @Override
    public String getName() {
        return "Magotan";
    }

    @Override
    public void brake(){
        System.out.println("Magotan 剎車挺好的,測試通過");
    }
}
工廠類

注意重載方法的返回類型已經修改稱對應的產品類,不在是Volkswagen類型了
ShangHaiVolkswagenFactory:負責生產上海汽車的工廠類

public class ShangHaiVolkswagenFactory extends VolkswagenFactory {

    public ShangHaiVolkswagen createVolkswagen(int id){
        ShangHaiVolkswagen volkswagen = null;
        switch(id){
            case Passat.ID:
                volkswagen = new Passat();
                break;
            case Polo.ID:
                volkswagen = new Polo();
                break;
            default:
                volkswagen = null;
        }
        return volkswagen;
    }
}

FAWVolkswagenFactory:負責生產一汽汽車的工廠類

public class FAWVolkswagenFactory extends VolkswagenFactory {

    @Override
    public FAWVolkswagen createVolkswagen(int productID) {
        FAWVolkswagen volkswagen = null;
        switch(productID){
            case Magotan.ID:
                volkswagen = new Magotan();
                break;
            case Sagitar.ID:
                volkswagen = new Sagitar();
                break;
            default:
                volkswagen = null;
        }
        return volkswagen;
    }

}

Client類:用來測試

public class Client {
    public static void main(String[] args) {
        System.out.println("開始測試上海大眾的車輛");
        ShangHaiVolkswagenFactory factory = new ShangHaiVolkswagenFactory();
        ShangHaiVolkswagen passat = factory.createVolkswagen(Passat.ID);
        passat.drive();

        ShangHaiVolkswagen polo = factory.createVolkswagen(Polo.ID);
        polo.drive();

        System.out.println("開始測試一汽大眾的車輛");
        FAWVolkswagenFactory fawFactory = new FAWVolkswagenFactory();

        FAWVolkswagen magotan = fawFactory.createVolkswagen(Magotan.ID);
        magotan.drive();
        magotan.brake();
        FAWVolkswagen sagitar = fawFactory.createVolkswagen(Sagitar.ID);
        sagitar.drive();
        sagitar.brake();
    }
}

打印log的也能夠正確的測試:
這裡寫圖片描述
通過下面的改變,Rrtoyewx將工廠抽象出生產上海大眾的車子和一汽大眾的車子的兩個工廠,並將一汽大眾和上海大眾的車子做了區分,形成兩個不同產品族的產品系列。並由兩個工廠分別對應去生產。等Rrtoyewx做完了這麼多後,終於發現原先的系統還是有漏洞的,還是有局限性的,好在及時的彌補。Rrtoyewx發現現有的系統無論處理一汽大眾的車子還是上海大眾的車子,甚至於再加一個進口大眾工廠的車子也夠用了。再以後的擴展也能得到了提升了。

工廠模式的優缺點

優點:擴展性,能夠處理不同產品系列的產品,通過具體的工廠去生成不同產品族的產品,擴展性較好。
缺點:類的個數較多。另外一個工廠的只能夠生產一個具體的產品。

抽象工廠類

多個抽象產品類 每個抽象產品類可以派生出多個具體產品類 一個抽象工廠類,可以派生出多個具體工廠類 每個具體工廠類可以創建多個具體產品類的實例

抽象工廠uml圖

這裡寫圖片描述
- AbstractFactory:抽象工廠類
- ConcreteFactoryA:具體工廠A,負責生產A和B的
- ConcreteFactoryB:具體工廠b,負責生產A和B的
- AbstractProductA,AbstractProductB:抽象的產品類
- ConcreteProductA1,ConcreteProductA2:具體產品A
- ConcreteProductB1,ConcreteProductB1:具體產品B
- Client:客戶端

舉個栗子

Rrtoyewx在做完上面測試工作之後,上面領導覺得Rrtoyewx工作很不錯,想將Rrtoyewx逐漸管理業務層的事(與人打交道),將Rrtoyewx升級了部門經理,同樣責任也多了起來了,Rrtoyewx不僅測試原先一些東西,而且需要做一個額外的事情,比如說保險之類。Rrtoyewx在查閱的保險的相關的書籍發現,一汽大眾的工廠需要一等保險,而上海大眾的車子需要二等保險。 Rrtoyewx 這個時候發現的保險和車子不屬於同一個產品。為了處理事務方便Rrotowx需要將原先的系統給升級一下。

升級後的系統的package圖
這裡寫圖片描述

新加了幾個類
Insurance:保險的抽象類
OneLevelInsurance:一等保險的實現類
TwoLevelInsurance:二等保險的實現類

Insurance類

public abstract class Insurance {
    public abstract String getName();
}

OneLevelInsurance類

public class OneLevellnsurance extends Insurance{

    @Override
    public String getName() {
        return "一級保險";
    }
}

TwoLevelInsurance類

public class TwoLevelInsurance extends Insurance {

    @Override
    public String getName() {
        return "二級保險";
    }
}

同時修改ShangHaiVolkswagenFactory和FAWVolkswagenFactory以及VolkswagenFactory的代碼
具體如下
VolkswagenFactory 添加一個生成Insurance類的方法

public abstract class VolkswagenFactory {

    public abstract Volkswagen createVolkswagen(int productID);

    public abstract Insurance bindInsurance();

    public final Volkswagen createVolkswagen(Class  clazz){
        Volkswagen volkswagen = null;
        try {
            volkswagen = clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return volkswagen;
    };
}

ShangHaiVolkswagenFactory綁定一等保險的對象

public class ShangHaiVolkswagenFactory extends VolkswagenFactory {

    public ShangHaiVolkswagen createVolkswagen(int id){
        ShangHaiVolkswagen volkswagen = null;
        switch(id){
            case Passat.ID:
                volkswagen = new Passat();
                break;
            case Polo.ID:
                volkswagen = new Polo();
                break;
            default:
                volkswagen = null;
        }
        return volkswagen;
    }

    @Override
    public Insurance bindInsurance() {  
        return new OneLevellnsurance();
    }
}

FAWVolkswagenFactory類:並定二等保險的對象

public class FAWVolkswagenFactory extends VolkswagenFactory {

    @Override
    public FAWVolkswagen createVolkswagen(int productID) {
        FAWVolkswagen volkswagen = null;
        switch(productID){
            case Magotan.ID:
                volkswagen = new Magotan();
                break;
            case Sagitar.ID:
                volkswagen = new Sagitar();
                break;
            default:
                volkswagen = null;
        }
        return volkswagen;
    }

    @Override
    public Insurance bindInsurance() {
        return new TwoLevelInsurance();
    }
}

Client客戶端測試的類

public class Client {
    public static void main(String[] args) {
        System.out.println("開始測試上海大眾的車輛");
        ShangHaiVolkswagenFactory factory = new ShangHaiVolkswagenFactory();
        ShangHaiVolkswagen passat = factory.createVolkswagen(Passat.ID);
        passat.drive();

        ShangHaiVolkswagen polo = factory.createVolkswagen(Polo.ID);
        polo.drive();
        Insurance shanghaiInsurance = factory.bindInsurance();
        System.out.println(shanghaiInsurance.getName());

        System.out.println("開始測試一汽大眾的車輛");
        FAWVolkswagenFactory fawFactory = new FAWVolkswagenFactory();

        FAWVolkswagen magotan = fawFactory.createVolkswagen(Magotan.ID);
        magotan.drive();
        magotan.brake();
        FAWVolkswagen sagitar = fawFactory.createVolkswagen(Sagitar.ID);
        sagitar.drive();
        sagitar.brake();
        Insurance fawInsurance = fawFactory.bindInsurance();
        System.out.println(fawInsurance.getName());
    }
}

打印log為:
這裡寫圖片描述
Rrtoyewx 做完這些,發現系統已經很健全了,不在為了測試車輛,只要與車輛相關的事宜的對象,由不同的工廠具體去實現。完成這麼多,Rrtoyewx 覺得天特別的藍,心情特別的舒服。

總結

工廠模式是一個創建型的模式 在任何使用A a = new A()的情況下,理論上說都能使用工廠模式。 在工廠模式分別的對應使用中,簡單工廠模式,注重具體生成的產品,而工廠模式,注重的同一個產品下的不同產品族的產品。如栗子中上海大眾的汽車和一汽大眾的汽車,抽象工廠模式更多事在與整體產品的架構上,不再是單一一個的抽象產品類。 工廠模式:一個抽象產品派生出去多個具體的產品,一個抽象工廠派生出多個具體的工廠,而一個具體的工廠對應生成的是一個具體的產品。 抽象工廠模式:多個抽象產品分別派生出多個具體的產品,一個抽象工廠派生成出多個具體的工廠,一個工廠對應生成多個具體的產品,這些多個抽象產品之間存在著聯系。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved