Android 架構(gòu)師之路6 設(shè)計模式之工廠模式

Android 架構(gòu)師之路 目錄

前言

工廠模式中,重要的是工廠類,而不是產(chǎn)品類。產(chǎn)品類可以是多種形式,多層繼承或者是單個類都是可以的。但要明確的,工廠模式的接口只會返回一種類型的實(shí)例,這是在設(shè)計產(chǎn)品類的時候需要注意的,最好是有父類或者共同實(shí)現(xiàn)的接口。
使用工廠模式,返回的實(shí)例一定是工廠創(chuàng)建的,而不是從其他對象中獲取的。
工廠模式返回的實(shí)例可以不是新創(chuàng)建的,返回由工廠創(chuàng)建好的實(shí)例也是可以的。

工廠模式主要是為創(chuàng)建對象提供了接口。工廠模式按照《Java與模式》中的提法分為三類:

  1. 簡單工廠模式(Simple Factory)
  2. 工廠方法模式(Factory Method)
  3. 抽象工廠模式(Abstract Factory)

1、工廠模式 - 簡單工廠模式

簡單工廠優(yōu)點(diǎn):客戶端可以免除直接創(chuàng)建產(chǎn)品對象的責(zé)任,而僅僅是“消費(fèi)”產(chǎn)品。簡單工廠模式通過這種做法實(shí)現(xiàn)了對責(zé)任的分割。

1.1、 簡單工廠模式UML圖
簡單工廠模式UML圖
1.2、 代碼實(shí)現(xiàn)
定義接口
/**
 * 地圖規(guī)范
 * @author Dream
 *
 */
public interface IMapView {
    enum MapType {
        // 空白背景模式常量
        MAP_TYPE_NONE,
        // 普通地圖模式常量
        MAP_TYPE_NORMAL,
        // 衛(wèi)星圖模式常量
        MAP_TYPE_SATELLITE
    }

    public View getView();

    public void setMapType(MapType mapType);
}
實(shí)現(xiàn)接口
public class BaiduMapView implements IMapView {

    @Override
    public View getView() {
        System.out.println("調(diào)用了百度地圖的getView");
        return null;
    }

    @Override
    public void setMapType(MapType mapType) {
        System.out.println("調(diào)用了百度地圖的setMapType");
    }

}

public class GaodeMapView implements IMapView {

    @Override
    public View getView() {
        System.out.println("調(diào)用了高德地圖的getView");
        return null;
    }

    @Override
    public void setMapType(MapType mapType) {
        System.out.println("調(diào)用了高德地圖的setMapType");
    }

}

創(chuàng)建工廠類
public class MapViewFactory {
    
    enum MapType{
        Baidu,
        Gaode
    }
    
    //使用上一節(jié)課的內(nèi)容---單例模式
    //懶漢式
    private static MapViewFactory mapViewFactory;
    
    private MapViewFactory(){
        
    }
    
    public static MapViewFactory getInstance(){
        if(mapViewFactory == null){
            mapViewFactory = new MapViewFactory();
            ArrayList<String> list = new ArrayList<String>();
            HashSet<String> hashSet = new HashSet<String>();
        }
        return mapViewFactory;
    }
    
    public IMapView getMapView(MapType mapType){
        IMapView mapView = null;
        switch (mapType) {
        case Baidu:
            mapView = new BaiduMapView();
            break;
        case Gaode:
            mapView = new GaodeMapView();
            break;
        }
        return mapView;
    }
    
}
調(diào)用主函數(shù)
public class SimpleTest {

    public static void main(String[] args) {
        // 客戶端和我們的地圖模塊耦合度大大降低了
        IMapView mapView = MapViewFactory.getInstance().getMapView(
                MapViewFactory.MapType.Baidu);
        mapView.getView();
        mapView.setMapType(IMapView.MapType.MAP_TYPE_NONE);
    }

}

運(yùn)行結(jié)果
獲得百度地圖MapView
設(shè)置了高德地圖類型
獲得高德地圖MapView
設(shè)置了高德地圖類型
1.3、Android源碼中使用
Android中簡單工廠--BitmapFactory,XmlPullParserFactory,CertificateFactory

2、工廠模式 - 工廠方法模式

工廠方法模式:把對象的實(shí)現(xiàn)延遲到子類完成
工廠方法優(yōu)點(diǎn):允許系統(tǒng)在不修改具體工廠角色的情況下引進(jìn)新產(chǎn)品。

2.1、 工廠方法模式UML圖
工廠方法模式UML圖
2.2、 代碼實(shí)現(xiàn)
產(chǎn)品接口與實(shí)現(xiàn)(Mapview)
//接口
public abstract class IMapView {
    public abstract void onStart();

    public abstract void onResume();

    public abstract void onDestory();
}
public class BaiduMapView extends IMapView {

    @Override
    public void onStart() {
        System.out.println("百度地圖onStart");
    }

    @Override
    public void onResume() {
        System.out.println("百度地圖onResume");
    }

    @Override
    public void onDestory() {
        System.out.println("百度地圖onDestory");
    }

}
public class GaodeMapView extends IMapView {

    @Override
    public void onStart() {
        System.out.println("高德地圖onStart");
    }

    @Override
    public void onResume() {
        System.out.println("高德地圖onResume");

    }

    @Override
    public void onDestory() {
        System.out.println("高德地圖onResume");
    }

}
抽象工廠
//抽象
public abstract class AbsMapFactory {
    // 我只定義標(biāo)準(zhǔn)
    public abstract <T extends IMapView> T createMapView(Class<T> clzz);
}

實(shí)現(xiàn)工廠
public class DefaultMapFactory extends AbsMapFactory {

    private static DefaultMapFactory defaultMapFactory;

    private DefaultMapFactory() {
    }

    public static DefaultMapFactory getInstance(){
        if(defaultMapFactory == null){
            defaultMapFactory = new DefaultMapFactory();
        }
        return defaultMapFactory;
    }


    @Override
    public <T extends IMapView> T createMapView(Class<T> clzz) {
        try {
            // 反射
            return clzz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
調(diào)用主函數(shù)
public class TestClient {
    
    public static void main(String[] args) {
        //工廠方法模式
        AbsMapFactory factory = DefaultMapFactory.getInstance();
        BaiduMapView mapView = factory.createMapView(BaiduMapView.class);
        mapView.onStart();

    }
    
}

運(yùn)行結(jié)果
百度地圖onStart
2.2、 Java或Android中源碼運(yùn)用

分析List集合、Set集合、Map集合 源碼
lterator:遍歷集合工廠方法抽象
Itr:具體的工廠實(shí)現(xiàn)類

lterator-> 抽象(工廠方法抽象) -->AdsMapFactory
Itr ->具體實(shí)現(xiàn)類->DefaultMapFactory
AbstractList-> 抽象 -->ImapView

      ArrayList-> 實(shí)現(xiàn)類-->  BaiduMapView

3、工廠模式 - 抽象工廠模式

為了增加導(dǎo)航模塊、全景圖口快、定位模塊而不僅僅是地圖模塊引入抽象工廠模式 (一組類要求相同約束)
抽象工廠優(yōu)點(diǎn):向客戶端提供一個接口,使得客戶端在不必指定產(chǎn)品具體類型的情況下,創(chuàng)建多個產(chǎn)品族中的產(chǎn)品對象

3.1、 抽象工廠模式UML圖
抽象工廠模式UML圖
3.2、 代碼實(shí)現(xiàn)
抽象工廠
public abstract class AbsMapFactory {

    public abstract AbsMapView createMapView();

    public abstract AbsMapNavigation createMapNavigation();

    public abstract AbsMapLocation createMapLocation();
}

各種具體工廠
public class GaodeMapFactory extends AbsMapFactory {

    @Override
    public AbsMapView createMapView() {
        return new GaodeMapView();
    }

    @Override
    public AbsMapNavigation createMapNavigation() {
        return new GaodeMapNavigation();
    }

    @Override
    public AbsMapLocation createMapLocation() {
        return new GaodeMapLocation();
    }

}
public class BaiduMapFactory extends AbsMapFactory {

    @Override
    public AbsMapView createMapView() {

        return  new BaiduMapView();
    }

    @Override
    public AbsMapNavigation createMapNavigation() {

        return new BaiduMapNavigation();
    }

    @Override
    public AbsMapLocation createMapLocation() {
        return new BaiduMapLocation();
    }

}
初始化工廠
public class DefaultFactory {


    //使用反射
    public static  <T extends AbsMapFactory> T creatProduct(Class<T> clz){
        AbsMapFactory api =null;
        try {
            api =(AbsMapFactory) Class.forName(clz.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return (T)api;
    }

}

工廠內(nèi)各產(chǎn)品

定位產(chǎn)品

public abstract class AbsMapLocation {
    
    /**
     * 定位
     */
    public abstract void location();
}

public class BaiduMapLocation extends AbsMapLocation {

    @Override
    public void location() {
        System.out.println("百度地圖定位...");
    }

}
public class GaodeMapLocation extends AbsMapLocation {

    @Override
    public void location() {
        System.out.println("高德地圖定位...");
    }

}

地圖產(chǎn)品

public abstract class AbsMapView {
    
    /**
     * Result for IActivityManager.startActivity: an error where the
     * start had to be canceled.
     * @hide
     */
    public abstract void onStart();

    public abstract void onResume();

    public abstract void onDestory();
}

public class BaiduMapView extends AbsMapView {

    
    @Override
    public void onStart() {
        System.out.println("百度地圖調(diào)用了onStart");
    }

    @Override
    public void onResume() {
        System.out.println("百度地圖調(diào)用了onResume");
    }

    @Override
    public void onDestory() {
        System.out.println("百度地圖調(diào)用了onDestory");
    }

}
public class GaodeMapView extends AbsMapView {

    @Override
    public void onStart() {
        System.out.println("高德地圖調(diào)用了onStart");
    }

    @Override
    public void onResume() {
        System.out.println("高德地圖調(diào)用了onResume");
    }

    @Override
    public void onDestory() {
        System.out.println("高德地圖調(diào)用了onDestory");
    }

}

導(dǎo)航產(chǎn)品

public abstract class AbsMapNavigation {
    
    /**
     * 路線規(guī)劃
     */
    public abstract void turnByTurn();
    
    //......很多功能方法
}
public class BaiduMapNavigation extends AbsMapNavigation {

    @Override
    public void turnByTurn() {
        System.out.println("百度地圖導(dǎo)航路線規(guī)劃");
    }

}
public class GaodeMapNavigation extends AbsMapNavigation {

    @Override
    public void turnByTurn() {
        System.out.println("高德地圖導(dǎo)航功能路線規(guī)劃");
    }

}

調(diào)用主函數(shù)


public class Test {
    
    public static void main(String[] args) {
        //直接初始化某地圖
        AbsMapFactory factory = new BaiduMapFactory();
        factory.createMapView().onStart();
        factory.createMapLocation().location();

        //反射初始化某地圖
        AbsMapFactory factory2 =  DefaultFactory.creatProduct(GaodeMapFactory.class);
        factory2.createMapView().onStart();
        factory2.createMapLocation().location();
    }
}
運(yùn)行結(jié)果
百度地圖調(diào)用了onStart
百度地圖定位...
高德地圖調(diào)用了onStart
高德地圖定位...
3.3、 Android源碼中使用

Activity、Service --- AbsMapView或者AbsMapNavgation
我們自定義的Activity(如BaseActivity)、Service ---BaiduMapView 或 BaiduMapNavgation
ActivityManager、ServiceManager --- 類似于我們通常所說的AbsMapFactory

總結(jié):

簡單工廠 : 用來生產(chǎn)同一等級結(jié)構(gòu)中的任意產(chǎn)品。(對于增加新的產(chǎn)品,無能為力)
工廠方法 :用來生產(chǎn)同一等級結(jié)構(gòu)中的固定產(chǎn)品。(支持增加任意產(chǎn)品)
抽象工廠 :用來生產(chǎn)不同產(chǎn)品族的全部產(chǎn)品。(對于增加新的產(chǎn)品,無能為力;支持增加產(chǎn)品族)

以上三種工廠 方法在等級結(jié)構(gòu)和產(chǎn)品族這兩個方向上的支持程度不同。所以要根據(jù)情況考慮應(yīng)該使用哪種方法。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 設(shè)計模式匯總 一、基礎(chǔ)知識 1. 設(shè)計模式概述 定義:設(shè)計模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 4,074評論 1 15
  • 今天學(xué)習(xí)下最常見的工廠模式,工廠模式細(xì)分下來有三大類: 他們的目標(biāo)都是一樣的:封裝對象的創(chuàng)建。但是實(shí)現(xiàn)手段和使用場...
    西木柚子閱讀 2,221評論 7 28
  • 1.接口基礎(chǔ)回顧 設(shè)計模式六大原則,其中依賴倒轉(zhuǎn)原則,強(qiáng)調(diào)我們應(yīng)該面向接口編程,那什么是接口?接口的作用? 接口如...
    孟婆湯不解渴閱讀 901評論 0 3
  • 最近看了一本書,《我在海軍航母上的8年》。書中記述了一個中國人在美國當(dāng)海軍的故事。讀這本書,是因?yàn)楹闷?。我的同事?..
    wifim閱讀 2,298評論 4 0
  • 夜深了。 陰沉沉的天空終于下起了大雨。 漆黑的夜幕被一道光劈成了兩半,整個城市被照的亮堂堂的,緊隨而至的是一...
    莫甘棠閱讀 315評論 0 0

友情鏈接更多精彩內(nèi)容