【java設計模式】(4)---工廠模式(案例解析)

設計模式之工廠模式

工廠模式分三種:簡單工廠模式(也叫靜態工廠模式),工廠方法模式(也叫多形性工廠),抽象工廠模式(也叫工具箱)下面會一一舉例。java

1、概念

一、什麼是工廠模式

     這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式工廠模式關心的是最終產出(建立)的對象, 而不關心建立的過程設計模式

二、工廠模式的優勢

工廠模式主要是爲建立對象提供過渡接口,以便將建立對象的具體過程屏蔽隔離起來,達到提升靈活性的目的。同時會給你係統帶來更大的可擴展性和儘可能少的修改量。(下面第三點會舉例說明)ide

三、什麼狀況使用工廠模式

這也是具體的說明工廠模式優勢。我我的認爲在任何須要生成複雜對象的地方,均可以考慮使用工廠模式。函數

咱們以線程池的舉例。工具

ThreadPoolExecutor類的四個構造方法。學習

public class ThreadPoolExecutor extends AbstractExecutorService { ..... public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler); ... }

咱們能夠看到線程池的構造函數要傳入的參數不少參數才能建立對象,可是其實這裏不少參數尤爲是後面3個參數基本上用默認值,而不需每次傳入。測試

那看下線程池的工廠模式(都是使用靜態工廠模式建立對象)。spa

Executors.newCachedThreadPool();       //建立一個緩衝池,緩衝池容量大小爲Integer.MAX_VALUE
Executors.newSingleThreadExecutor();   //建立容量爲1的緩衝池
Executors.newFixedThreadPool(int);     //建立固定容量大小的緩衝池

下面是這三個靜態方法的具體實現:線程

public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); } public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }

是否是都已經傳入一些默認值,這讓咱們無需再思考在構造函數中應該傳入什麼值而苦惱,而直接經過工廠模式獲取一個對象。設計

 

2、簡單工廠模式

學習簡單工廠模式的時候我用的是一個與人類有相關的例子。人類在世界分爲男人和女人,首先定義一個NvWa(女媧)產品的抽象接口

/** * 產品的抽象接口 女媧 */
public interface NvWa { public void say(); }

而後定義男人和女人,一樣都有說話的方法。

/** * man 男人 */
public class Man implements NvWa { @Override public void say() { System.out.println("男人"); } } 
/**女人 */
public class Women implements NvWa { @Override public void say() { System.out.println("女人"); } }

最後寫一個工廠類,用來創造男人和女人。第一種方式是使用邏輯判斷的方式實現的。

/** * 簡單工廠 */
public class SampleFactory { public static NvWa makeNvWa(String type){ if(type.equals("man")){ NvWa man = new Man(); return man; }else if(type.equals("wommen")){ NvWa women = new Women(); return women; }else{ System.out.println("生產不出來"); return null; } } }

第二方式是使用java的放射實現的(推薦)

/** * 簡單工廠放射實現 */
public class SampleFactory1 { public static NvWa makeNvWa(Class c){ NvWa nvwa = null; try { nvwa= (NvWa) Class.forName(c.getName()).newInstance(); } catch (ClassNotFoundException e) { System.out.println("類不存在"); e.printStackTrace(); } return nvwa; } }

反射測試類代碼

package com.roc.factory; /** * 簡單工廠測試*/
public class Client { public static void main(String[] args) { NvWa man = SampleFactory1.makeNvWa(Man.class); man.say(); NvWa women = SampleFactory1.makeNvWa(Women.class); women.say(); } }

總結下:

簡單工廠模式實質:是由一個工廠類根據傳入的參數,動態決定應該建立哪個產品類(這些產品類繼承自一個父類或接口)的實例。簡單工廠模式的建立目標,全部建立的對象都是充當這個角色的某個具體類的實例。

簡單工廠模式缺點:嚴重違反開閉原則,由於這個時候若是女王要造人妖的話,那確定要修改工廠的方法,這就違反了開閉原則:修改關閉,對擴展開放。

 

3、工廠方法模式

在簡單的工廠模式裏,咱們建立了一個相似工具的類來建立相應的具體類對象。正由於其太過簡單,不符合開閉原則。

工廠方法模式就是把簡單工廠中具體的工廠類,劃分紅兩層:抽象工廠層+具體的工廠子類層。(就是把具體抽象類多添加一層)

網上盜一張圖(很是完美的圖)

具體例子(把上面的具體實現工廠拆分)

NvWaFactory(造人工廠)

public abstract class NvWaFactory { public abstract NvWacreate(); }

 Man工廠(具體工廠子類)

public class ManFactory extends NvWaFactory { @Override public NvWa create() { return new Man(); } }

WoMen工廠(具體工廠子類)

public class WomenFactory extends NvWaFactory { @Override public NvWa create() { return new Women(); } }

測試類

/** * 工廠方法模式: */ NvWaFactory factory1 = new ManFactory(); Man man= factory1.create(); man.say();

工廠方法與簡單工廠的區別

能夠看出,普通工廠模式特色:不只僅作出來的產品要抽象, 工廠也應該須要抽象。

工廠方法的好處就是更擁抱變化。好比如今在須要造人妖你只要在寫個具體的人妖工廠,而不用像簡單工廠去修改makeNvWa方法,因此工廠方法模式不會違反開閉原則

 

4、抽象工廠模式

從上面的工廠方法中的結構圖中,咱們能夠看到其中的具體工廠A和B是兩個徹底獨立的。二者除了都是抽象工廠的子類,沒有任何其餘的交集。

能夠理解工廠方法模式都是單產品系的。抽象工廠是多產品系

再盜一張圖,這張圖解釋很是到位,下面例子若是沒理解,那麼再仔細思考這張圖

咱們修改下上面的工廠方法中的總工廠

public abstract class AbstractFactory { /** * 生產人類 */
    public abstract NvWa createNvWa(); /** * 生產汽車(這個類就不具體些了,理解就好) */
    public abstract Car createCar(); }

具體工廠1

/*具體工廠1:這裏生產男人和寶馬車 */
public class Factory1 extends AbstractFactory { @Override public NvWa createNvWa() { return new Man(); } @Override public Car createCar() { return new Bmw(); } }

 具體工廠2

/*具體工廠2:這裏生產女人和奔馳車 */
public class Factory2 extends AbstractFactory { @Override public NvWa createNvWa() { return new Women(); } @Override public Car createCar() { return new Bc(); } }

 功能測試

 有了這些東西,那麼咱們就來好好生產一些產品吧.

public class FactoryTest { public static void main(String[] args) { //工廠1生產男人和寶馬
        AbstractFactory factory1 = new Factory1(); Man man = factory1.createNvWa(); Bmw bmw = factory1.createCar(); //工廠2生產女人和奔馳
        AbstractFactory factory2 = new Factory2(); Women women = factory2.createNvWa(); Bc bc = factory2.createCar(); } }

 我的總結下

簡單工廠模式它的優勢就是簡單,並且違背了開閉原則。不過靜態工廠模式在實際中用到比較多。工廠方法模式修復了開閉原則,但它也有一個缺點每次新增一個具體產品類,也要同時新增一個具體工廠類,會形成類太多。

工廠方法模式比抽象工廠也會用的多,由於抽象工廠結構不像工廠方法那樣清晰。

 

 

想太多,作太少,中間的落差就是煩惱。想沒有煩惱,要麼別想,要麼多作。中校【6】   

相關文章
相關標籤/搜索