Android設(shè)計模式之(4)----工廠方法模式

工廠方法模式


比如富士康是一個工廠,為其他外部廠商提供相同或者不同的產(chǎn)品,而外部廠商不用關(guān)心富士康內(nèi)部的實現(xiàn)過程,只需要接受結(jié)果即可。如果有新的產(chǎn)品,也只需要告訴富士康,富士康負責(zé)生產(chǎn)輸出就好。

因此工廠模式可大幅度降低模塊之間的耦合,加強擴展性。

應(yīng)用場景

需要生成一個或者多個復(fù)雜對象的具體實現(xiàn)

工廠模式分類

  • 工廠方法模式
    • 標(biāo)準(zhǔn)工廠
    • 簡單工廠
    • 反射工廠
    • 緩存工廠
    • 私有工廠
  • 抽象工廠模式

本文主要介紹工廠方法模式。

工廠方法模式特點

  • 一個抽象類可以實現(xiàn)多個具體類

具體實現(xiàn)

Q:使用工廠模式來判斷一個程序猿他是具體的什么樣的程序猿(PHP,Android,iOS,Java等等)

(一)標(biāo)準(zhǔn)工廠方法

1.建立一個接口來獲取程序猿類型

public interface CodeMonkey {
    public  void showCodeMonkeyType();//展示是什么類型的程序猿
}

2.實現(xiàn)接口生成不同類型的程序猿

Android程序猿:

public class AndroidCodeMonkey implements  CodeMonkey {
    @Override
    public void showCodeMonkeyType() {
        System.out.println("我是Android攻城獅");
    }
}

iOS程序猿:

public class IosCodeMonkey implements  CodeMonkey {
    @Override
    public void showCodeMonkeyType() {
        System.out.print("我是iOS攻城獅");
    }
}

3.建立抽象的工廠接口

public abstract class Factory {
    public abstract CodeMonkey showCodeMonkeyType() ;
}

4.通過抽象的工廠接口進行具體類的實現(xiàn)

public class AndroidMonkeyFactory extends Factory {

    @Override
    public CodeMonkey showCodeMonkeyType() {
        return new AndroidCodeMonkey();
    }
}
public class IosMonkeyFactory extends Factory {
    @Override
    public CodeMonkey showCodeMonkeyType() {
        return new IosCodeMonkey();
    }
}

5.具體調(diào)用

CodeMonkey codeMonkey = new AndroidCodeMonkey();
        codeMonkey.showCodeMonkeyType();

        new IosCodeMonkey().showCodeMonkeyType();

6.輸出結(jié)果

我是Android攻城獅

我是iOS攻城獅

程序猿(產(chǎn)品)在創(chuàng)建過程中都是通過接口來進行生成,生成某一類型程序猿時降低了使用者和產(chǎn)品本身耦合

(二)簡單工廠模式(靜態(tài)工廠模式)

靜態(tài)工廠的方法是靜態(tài)的,不允許外部進行擴展更改,如果有內(nèi)容的更改需要對當(dāng)前靜態(tài)工廠進行更改。

代碼示例:

public class CodeMonkeyEasyFactory {
    public final static String GENERATE_IOS = "android";
    public final static String GENERATE_ANDROID = "ios";
    public static CodeMonkey generateCodeMonkey(String flag) throws Exception {
        CodeMonkey codeMonkey = null;
        switch (flag){
            case GENERATE_ANDROID:
                codeMonkey =  new AndroidCodeMonkey();
                break;
            case GENERATE_IOS:
                codeMonkey =  new IosCodeMonkey();
                break;

            default:
                throw new Exception("UNDEFINED FLAG");
        }
        return codeMonkey;
    }
}

上述靜態(tài)工廠在內(nèi)部已經(jīng)定義了iOS和Android的靜態(tài)常亮,使用過程中只需要外部傳入具體的數(shù)值,內(nèi)部進行判斷即可,但是若有新的程序猿產(chǎn)生,除了實現(xiàn)具體的程序猿,還需要對靜態(tài)工廠擴展增加。
外部調(diào)用:

CodeMonkeyEasyFactory.generateCodeMonkey(CodeMonkeyEasyFactory.GENERATE_ANDROID).showCodeMonkeyType();
CodeMonkeyEasyFactory.generateCodeMonkey(CodeMonkeyEasyFactory.GENERATE_IOS).showCodeMonkeyType();

顯示結(jié)果:

我是Android攻城獅

我是iOS攻城獅

(三)反射工廠

只需要實現(xiàn)具體的產(chǎn)品類型而不需要修改工廠,通過反射拋到上層直接讓外部使用獲取。

代碼示例:

1.泛型類型約束將具體類型拋到上層工廠進行處理

public abstract class IGenerator {
    public abstract <T extends CodeMonkey>T generateCodeMonkey(Class<T> clazz) throws Exception;
}

2.實現(xiàn)具體產(chǎn)品內(nèi)容

public class CodeMonkeyReflexFactory extends IGenerator {
    @Override
    public <T extends CodeMonkey> T generateCodeMonkey(Class<T> clazz) throws Exception {
        CodeMonkey codeMonkey = null;
        codeMonkey = (CodeMonkey) Class.forName(clazz.getName()).newInstance();
        return (T)codeMonkey;
    }
}

調(diào)用方式:

 new CodeMonkeyReflexFactory().generateCodeMonkey(AndroidCodeMonkey.class).showCodeMonkeyType();

顯示結(jié)果:

我是Android攻城獅

(四)緩存工廠

將復(fù)雜對象或者頻繁使用的內(nèi)容作為一個長期的存儲,再次使用時直接進行提取

代碼示例:

public class CodeMonkeyCacheFactory  extends IGenerator {
    private Map<String, CodeMonkey> map = new HashMap<>();

    @Override
    public <T extends CodeMonkey> T generateCodeMonkey(Class<T> clazz) throws Exception {
        CodeMonkey CodeMonkey = null;
        if (map.containsKey(clazz.getName()))
            CodeMonkey = map.get(clazz.getName());
        else {
            CodeMonkey = (CodeMonkey) Class.forName(clazz.getName()).newInstance();
            map.put(clazz.getName(), CodeMonkey);
        }
        return (T) CodeMonkey;
    }
}

將具體的產(chǎn)品類型存儲于hasmap,再次使用時可直接提取使用。

調(diào)用方式:

 new CodeMonkeyCacheFactory().generateCodeMonkey(AndroidCodeMonkey.class).showCodeMonkeyType();
 

顯示結(jié)果:

我是Android攻城獅

(五) 私有產(chǎn)品構(gòu)造

限制外部使用new XXX()的方式進行創(chuàng)建

public class CodeMonkeyPrivateFactory extends IGenerator {
    public <T extends CodeMonkey> T generateCodeMonkey(Class<T> clazz) throws Exception {
        CodeMonkey iPhone = null;
        Class phone = Class.forName(clazz.getName());
        //拿到構(gòu)造器不檢測權(quán)限
        phone.getDeclaredConstructor().setAccessible(true);
        iPhone = (CodeMonkey) phone.newInstance();
        return (T) iPhone;
    }
}

調(diào)用方式:

 new CodeMonkeyPrivateFactory().generateCodeMonkey(AndroidCodeMonkey.class).showCodeMonkeyType();

顯示結(jié)果:

我是Android攻城獅

總結(jié)

以上就是工程模式的介紹.降低模塊耦合,提高擴展性,有新的產(chǎn)品內(nèi)容出現(xiàn)只需要擴展工廠即可完成。

github代碼地址

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

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,741評論 25 709
  • 設(shè)計模式匯總 一、基礎(chǔ)知識 1. 設(shè)計模式概述 定義:設(shè)計模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 4,073評論 1 15
  • 大年初二,一早趁家里人都還沒起床,一個人訂了票,去看《西游·伏妖篇》。初二的早晨街上清冷,等了一陣子,才看到一輛出...
    立春快樂閱讀 302評論 0 0
  • 記得這句話嗎? 多么希望有一天突然驚醒, 發(fā)現(xiàn)自己是在小學(xué)的一節(jié)課上睡著了, 現(xiàn)在經(jīng)歷的一切都是一場夢,...
    小小只麋鹿閱讀 279評論 0 1
  • 讀高中時,從學(xué)校走到公交車站會下一個很大的坡,大概有800米,路邊有一個中年女人,除了下雨,她每天都在那里擺攤,從...
    苛娃閱讀 425評論 0 2

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