android中用到了太多的工廠類,其中有用工廠方法模式的,固然也有不少工廠並非使用工廠方法模式的,只是工具管理類。
今天以ThreadFactory舉例說明一下簡單工廠模式和工廠方法模式。
工廠方法模式,Factory Method,簡單的方式,不簡單的應用。java
1.意圖
定義一個用於建立對象的接口,讓子類決定實例化哪一個類。工廠方式模式使一個類的實例化延遲到其子類。
熱門詞彙:虛構造器 延遲 建立對象 子類 android
2.結構圖和代碼
咱們先看看標準的工廠方法結構圖:閉包

先抽象的產品類,抽象的工廠類,而後用客戶端具體的工廠生產相應的具體的產品,可是客戶端並不知道具體的產品是怎麼生產的,生產的過程封裝在工廠裏。因此說,某種程度上,工廠方法模式改變了咱們直接用new建立對象的方式,一個很好的開始,意義重大。
以ThreadFactory爲例:app

這張圖其實和本來的結構圖有細微的區別,那就是參數化得工廠,並且從業務意義上也有些不一樣,可是思想是同樣的。
咱們來看下具體的代碼:ide
- public interface Runnable {
- public abstract void run();
- }
-
- public interface ThreadFactory {
- Thread newThread(Runnable r);
- }
下面是具體的實現:
好比AsyncTask類中工廠的具體實現以下:工具
- 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());
- }
- };
看到這裏,咱們一方面爲它的生產便利性感嘆,一方面又爲沒建立某類產品都要建立一個工廠而感到繁瑣,因此咱們下面介紹簡單工廠,它的結構圖以下:oop

簡單工廠把抽象工廠去掉了,你就建立一個專門生產某類產品就好。在一些特定而又不負責的領域很是實用方便套用這個模式。
在android中的Connection類中使用到了這個類:this

其中Connection這個抽象類,既充當抽象產品類,也充當具體工廠類。
由於這種狀況下,咱們每每須要的是立刻生產子類,getConnection方法每每是靜態的,因此簡單工廠,也叫靜態工廠方法。
咱們看看代碼以下:spa
- abstract class Connection{
- static Connection getConnection(
- Context context, HttpHost host, HttpHost proxy,
- RequestFeeder requestFeeder) {
-
- if (host.getSchemeName().equals("http")) {
- return new HttpConnection(context, host, requestFeeder);
- }
-
-
- return new HttpsConnection(context, host, proxy, requestFeeder);
- }
- }
這就是簡單工廠,一個很簡單的參數化工廠,真的很簡單。.net
3.效果
1.建立型模式;
2.參數化工廠方法模式獲得相應的對象;
3.爲子類提供掛鉤;
4.鏈接平行的類層次。
另一個例子:
先假設要作這樣的一個設計。設計一個Usb功能的接口,具備store(存儲)和takeAlong(攜帶方便)兩個行爲。而後要設計兩個產品,一個是 Phone(手機),另外一個是Camera(照相機),很顯然,它們均可以是 Usb的實現類。爲了便於統一管理和建立,咱們很容易就能設計出一個簡單的工廠模式。
(1)普通的工廠方法
首先,咱們能夠畫出相關的設計圖:

代碼實現以下:
定義Usb接口
- public interface Usb {
-
- void store();
-
- void takeAlong();
- }
Phone類
- public class Phone implements Usb {
-
- @Override
- public void store() {
-
- System.out.println("this is Phone usb!");
- }
-
- @Override
- public void takeAlong() {
-
-
- }
-
- public void call() {
-
- }
-
- public void sms() {
-
- }
-
- }
Camera類
- public class Camera implements Usb {
-
- @Override
- public void store() {
- System.out.println("this is Camera usb!");
- }
-
- @Override
- public void takeAlong() {
-
-
- }
-
- public void takePhotos() {
-
- }
-
- }
建立一個簡單的工廠類UsbFactory1,負責生產
- public class UsbFactory1 {
-
- public Usb produce(String type) {
- if ("phone".equals(type)) {
- return new Phone();
- } else if ("camera".equals(type)) {
- return new Camera();
- } else {
- System.out.println("請輸入正確的類型!");
- return null;
- }
- }
- }
子類實例化經過工廠類去建立,如要建立camera,
- UsbFactory1 factory1 = new UsbFactory1();
- Usb usb1 = factory1.produce("camera");
- usb1.store();
輸出:this is Camera usb!
總結:實現了工廠模式的基本功能,可是須要傳參去控制,會出現不少不肯定的問題,能夠在工廠類中定義不一樣產品的生產,就是以下介紹的工廠多方法生產。
(2)工廠多方法
只要在UsbFactory中再定製一下就行,業務更加分明

根據設計修改工廠類
- **
- * 多個工廠類方法
- *
- * @author xuzhaohu
- *
- */
- public class UsbFactory2 {
-
- public Usb producePhone() {
- return new Phone();
- }
-
- public Usb produceCamera() {
- return new Camera();
- }
-
- }
一樣,要實例化某個子類對象,則能夠這樣去調用:
- UsbFactory2 factory2 = new UsbFactory2();
- Usb usb2 = factory2.producePhone();
- usb2.store();
輸出:this is Phone usb!
這樣是否是讓業務邏輯更加清晰了一些呢!
可是若是在多處都要調用生產的話,不能每次都經過實例化工廠類而後去生產吧,這時候能夠怎麼樣呢?
對,能夠經過類訪問,在工廠類中加上static方法。
- public class UsbFactory3 {
-
- public static Phone producePhone() {
- return new Phone();
- }
-
- public static Camera produceCamera() {
- return new Camera();
- }
- }
那麼這時候能夠直接不用實例化工廠類去訪問了
- Usb usb3 = UsbFactory3.producePhone();
- usb3.store();
輸出:this is Phone usb!
這樣就更加方便了一些。通常狀況下,這樣就基本能知足需求了,可是若是如今需求又要增長生產另一個實現類產品Phone1,這時候確定須要修改工廠類,在工廠類中增長一個新類型的生產Phone1方法。從設計的角度上講,可能違背了 閉包(對擴展要開放對修改要關閉) 的設計原則,爲了避免違背這個原則,能夠抽象工廠方法去設計,下面將講到。
(3)抽象的工廠方法
爲了避免修改工廠中方法,咱們能夠對每一個產品都建立相應工廠類去實現生產。這時候能夠經過一個接口 Provider 去定義生產(produce)這個行爲,而後讓每一個產品的工廠類都實現這個接口。這樣若是有新的產品要生產的話只須要先實現一個工廠類就行。以下設計
生產接口Provider
- public interface Provider {
-
- Usb produce();
- }
每一個產品都有本身的工廠
PhoneFactory工廠
- public class PhoneFactory implements Provider {
-
- @Override
- public Usb produce() {
-
- return new Phone();
- }
-
- }
CameraFactory工廠
- public class CameraFactory implements Provider {
-
- @Override
- public Usb produce() {
-
- return new Camera();
- }
-
- }
每個產品能夠根據本身的業務來去工廠生產產品,如要生產Camera
-
- Provider provider = new CameraFactory();
- Usb usb4 = provider.produce();
- usb4.store();
輸出:this is Camera usb!