Android中的設計模式-Factory 方法模式

來源:互聯網
上載者:User

標籤:設計模式   原廠模式   Factory 方法   android   

簡單工廠&Factory 方法

一直以來總是分不清簡單工廠,Factory 方法,抽象工廠這三個設計模式的區別,倒不是不理解其區別,而是總是記憶混淆,傻傻分不清楚,所以再重新總結一下區別,並記錄下來,下次再混淆時,可以拿出來看看。這節先說簡單工廠和Factory 方法,下一節再說抽象工廠。

Factory 方法中其實就包含了簡單工廠,簡單工廠也稱為靜態Factory 方法,

簡單原廠模式(Simple Factory)類圖


簡單原廠模式又稱為靜態Factory 方法模式,是Factory 方法模式的一種,簡單原廠模式的實質是由一個工廠類根據傳入的參數,動態決定應該建立哪一個產品類(這些產品類繼承自一個父類或介面)的執行個體。注意這裡工廠類傳入的參數,是工廠類建立產品的依據,可以是一個字串,也可以是自己定義的Enum或者Int值。

以一個汽車工廠為例,可以生產3種不同類型的汽車,SUV,Sedan,MPV,每個汽車都有drive方法。如果不使用簡單工廠而是直接建立的話,如下面的例子。

public class User {    public static SUV suv;    public static void main(String[] args) {        suv=new SUV();        suv.drive();    }}class SUV{    public void drive(){        System.out.println("SUV is driving");    }}class Sedan{    public void drive(){        System.out.println("Sedan is driving");    }}class MPV{    public void drive(){        System.out.println("MPV is driving");    }}

乍看起來沒問題,想要什麼產品,那就直接建立一個就好了,不過問題在於,對於使用產品的類,只能持有對應產品的對象,例如上面的例子,我持有SUV的對象,然後建立SUV的對象,當有一天有了新的產品了,並且需要替換SUV。還需要修改使用的主體。這就使使用產品的主體和產品緊緊耦合在了一起。不利於代碼的複用和拓展。

把上面的代碼稍微修改一下,將所有車輛抽象為一個Vehicle介面,讓User持有一個Vehicle對象,建立一個工廠類,根據傳入的參數不同,返回不同的對象給User使用。並且工廠類建立產品的函數是靜態,這樣就不需要先建立一個工廠類了。

代碼:
interface Vehicle{    public void drive();}class SUV implements Vehicle {    @Override    public void drive(){        System.out.println("SUV is driving");    }}class Sedan implements Vehicle{    @Override    public void drive() {        System.out.println("Sedan is driving");    }}class MPV implements Vehicle{    @Override    public void drive(){        System.out.println("MPV is driving");    }}enum VehcleType{    suv,sedan,mpv}public class SimpleFactory {    public static Vehicle makeVehicle(VehcleType type){        switch(type){        case suv:            return new SUV();        case sedan:            return new Sedan();        case mpv:            return new MPV();        default:            break;        }        return null;    }}

測試代碼:

public class User {    public static Vehicle mVehicle;    public static void main(String[] args) {        mVehicle=SimpleFactory.makeVehicle(VehcleType.suv);        mVehicle.drive();    }}

這樣就好多了。不過有些情況還是不夠好,比如:
當我需要生產一種新的車型,比如敞篷車 Convertible. 但是我在SimpleFactory.makeVehicle時,並沒有這種車型,那就需要修改SimpleFactory類讓它增加一個case判斷,並建立一個Convertible對象。但是我們並不希望SimpleFactory這個工廠類開放給使用者,也就造成了沒辦法去增加車型。 如何才能讓User任意的增加車型呢? 這就擴充出了Factory 方法模式

Factory 方法模式(Factory Method)

繼續上面的說,User可以只知道一個Vehicle介面對象和一個Factory介面對象,對於SUV來說它實現了Vehicle介面,同時也需要SUVFactory來實現Factory介面並建立它,這樣對User來說,只需要建立一個SUVFactory對象,然後通過SUVFactory類建立一個SUV對象。 如果客戶自己想增加一個Convertible產品。那隻需要實現自己的Convertible類和ConvertibleFactory類。然後用同樣的方式生產即可。

類圖

代碼:車輛相關
public interface Vehicle {    public void drive();}class SUV implements Vehicle {    @Override    public void drive(){        System.out.println("SUV is driving");    }}class Sedan implements Vehicle{    @Override    public void drive() {        System.out.println("Sedan is driving");    }}class MPV implements Vehicle{    @Override    public void drive(){        System.out.println("MPV is driving");    }}
工廠相關
public interface Factory {    public Vehicle makeVehicle();}class SUVFactory implements Factory{    @Override    public Vehicle makeVehicle() {        return new SUV();    }}class SedanFactory implements Factory{    @Override    public Vehicle makeVehicle() {        return new Sedan();    }}class MPVFactory implements Factory{    @Override    public Vehicle makeVehicle() {        return new MPV();    }}

客戶類:
public class User {
public static Vehicle mVehicle;
public static Factory mFactory;
public static void main(String[] args) {
mFactory=new SUVFactory();
mVehicle=mFactory.makeVehicle();
mVehicle.drive();
}

}

這時,我們想要改生產Convertible車輛,只需要增加Convertible和對應工廠,並修改客戶類的實現即可:

class Convertible implements Vehicle{    @Override    public void drive(){        System.out.println("Convertible is driving");    }}
class ConvertibleFactory implements Factory{    @Override    public Vehicle makeVehicle() {        return new Convertible();    }}
public class User {    public static Vehicle mVehicle;    public static Factory mFactory;    public static void main(String[] args) {        mFactory=new ConvertibleFactory();        mVehicle=mFactory.makeVehicle();        mVehicle.drive();    }}

這時,生產出來的就是Convertible產品了。
設計模式的應用還是要根據其使用情境來決定,簡單工廠升級為Factory 方法,是因為需要封裝工廠類,提供給客戶類最大的自由和擴充性,但又對工廠的內部邏輯進行封裝。
但不是說簡單工廠就沒有Factory 方法好用,當客戶類User本身也是內部封裝的一部分,我們可以很方便的去修改工廠類,或者產品的增加可能很小,比如Phone,本來就只有GSMPhone,CDMAPhone,過了很久,突然出現了CDMALTEPhone,那也只需要在工廠類中增加這個類的生產即可。也許再出現一個新的XXXPhone也要幾年之後了。

Android中的Factory 方法簡單工廠

Android源碼中有很多的Factory 方法的使用,其中大多是靜態Factory 方法,也即是最開始說的簡單工廠,前面也說過了,使用什麼工廠是根據需求來看的,靜態Factory 方法是Factory 方法的一個特例,雖然不似Factory 方法那麼靈活,但是對於很多不需要建立多個工廠來建造產品的情況下,靜態Factory 方法反而簡單快捷。

例如BitmapFactory,通過public static Bitmap decodeFile(String pathName)靜態方法,從檔案中讀取並建立Bitmap對象。
還比如Telephony中的PhoneFactory,通過public static void makeDefaultPhones(Context context) 靜態方法建立,並通過PhoneFactory.getDefaultPhone()擷取建立好的
還有NetworkStatsFactory,WebViewFactory這些都是簡單工廠的應用。
除了Framework,很多系統應用也用到了Factory 方法,就不一一列舉了。

Factory 方法

Java庫中的ThreadFactory類作為抽象工廠,定義如下:

public interface ThreadFactory {    Thread newThread(Runnable r);}

Android中常用的AsyncTask,在其中就建立了一個具體的工廠(還有MMS應用中的BackgroundLoaderThreadFactory的實現,類似):

    private static final ThreadFactory  sThreadFactory = new ThreadFactory() {        private final AtomicInteger mCount = new AtomicInteger(1);        public Thread newThread(Runnable r) {            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());        }    };

ThreadFactory的使用一般用在作為建立ThreadPoolExecutor的參數,在ThreadPoolExecutor中調用getThreadFactory().newThread()來建立一個背景工作執行緒,這裡面Runnable可以理解為抽象產品,而Thread則是具體產品。

Android中的設計模式-Factory 方法模式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.