【設計模式】——工廠方法


【一個故事】

    

    話說三國時期,西涼刺史董卓乘朝野之戰,統領二十萬大軍進駐洛陽,廢了少帝,立了獻帝,自封爲相國(還挺好意思)。董卓爲人殘暴,欺主弄權,朝中正直大臣都想殺之而後快,然而,董卓權傾朝野,位高權重,身邊還有號稱天下第一勇武呂布陪伴左右(呂布這不是助紂爲虐嗎),無人敢近,衆大臣只能恨於心中。校尉曹操(主角出場),足智多謀,早有殺董之心。一日,在大司徒王允處借的七星寶刀,進府行刺董卓。

    曹操得了七星寶刀,喜出望外,心想,這下我可有出頭之日了,只要殺了董賊,我就是英羣,名垂千古,萬世流芳!(暗笑)哈哈……於是身藏寶刀,來到相府,等待刺殺時機。

    董卓見到曹操,問:“孟德爲何來得這麼晚?”曹操說:“我的馬兒比較瘦,跑不快。”董卓說:“沒事,我有的是好馬,讓呂布去給你挑一匹。”於是自己就躺在榻上休息了,呂布也出去了,曹操一看,機會來了,急抽刀欲刺之,但是寶刀光芒四射,被銅鏡反射到了董卓的臉上,董卓猛然起身,問:“你要幹嘛?”恰巧,挑馬的呂布回來了,機智的曹操說:“偶得寶刀一把,欲獻給丞相。”董卓順手接過寶刀:“不錯,好刀!”曹操又說:“我想試試馬,希望丞相能恩准。”於是曹操借馬飛馳而去。過了一會兒,董卓一拍大腿說:“上當了!!!”(反射弧真長),但是曹操早已不見了蹤跡。


【模式定義】

    

    工廠方法模式(Factory Method Pattern),就是定義一個創建產品對象得工廠接口,讓子類決定實例化哪一種實例對象,也就是將實際創建實例對象得工作推遲到子類當中,核心工廠類不再負責具體產品得創建。

    工廠方法模式是對簡單工廠模式進行了抽象。


【靜態建模】

 

大司徒王允——抽象工廠(負責提供寶刀)ISwordFactory

各類寶刀——抽象產品(各類寶刀)AbstractSword

校尉曹操——具體工廠(獲得七星寶刀)Caocao

七星寶刀——具體產品(寶刀中的一類)QixingSword





【代碼實現】


工程結構圖:



1、抽象寶刀——AbstractSword

package com.demo.factory.model;

/**
 * 定義抽象寶刀
 * Created by 麗傑 on 2017/6/3.
 */
public abstract class AbstractSword {
    //寶刀的名稱
    private String name;

    //抽象寶刀的構造方法
    public AbstractSword(){
    }

    //獲得寶刀名稱
    public String getName() {
        return name;
    }

    //設置寶刀名稱
    public void setName(String name) {
        this.name = name;
    }
}

2、具體寶刀(七星寶刀)——QixingSword

package com.demo.factory.model.object;

import com.demo.factory.model.AbstractSword;

/**
 * 七星寶刀類
 * Created by 麗傑 on 2017/6/3.
 */
public class QixingSword extends AbstractSword{

    /**
     * 構造方法設置寶刀的名稱
     */
    public QixingSword(){
        this.setName("七星寶刀");
    }
}

3、抽象寶刀工廠——ISwordFactory

package com.demo.factory.itf;

import com.demo.factory.model.AbstractSword;

/**
 * 寶刀工廠
 * Created by 麗傑 on 2017/6/3.
 */
public interface ISwordFactory {
    /**
     * 生產各類寶刀(返回值是抽象寶刀類型)
     */
    public AbstractSword createSword();
}


4、具體寶刀工廠(生產七星寶刀)——Caocao
package com.demo.factory;

import com.demo.factory.itf.ISwordFactory;
import com.demo.factory.model.AbstractSword;
import com.demo.factory.model.object.QixingSword;

/**
 * 曹操具體工廠
 * Created by 麗傑 on 2017/6/3.
 */
public class Caocao implements ISwordFactory {
    /**
     * 實現ISwordFactory接口的createSword方法,生產七星寶刀
     */
    public AbstractSword createSword(){
        return new QixingSword();
    }
}

5、主應用程序——MainApp

package com.demo;

import com.demo.factory.Caocao;
import com.demo.factory.Caocao2;
import com.demo.factory.model.AbstractSword;
import com.demo.factory.itf.ISwordFactory;

/**
 * Created by 麗傑 on 2017/6/3.
 */
public class MainApp {

    public static void main(String[] args){
        //創建曹操實例對象(返回使用接口類型ISwordFactory)
        ISwordFactory swordFactory = new Caocao();
        //獲得寶刀實例——七星寶刀c
        AbstractSword sword = swordFactory.createSword();
        //刺殺董卓
        System.out.print("曹操使用"+sword.getName()+"刺殺董卓!");
    }
}


6、運行效果


【八星寶刀】

    刺殺一次失敗後,曹操痛定思痛,決定“二進宮”,感覺八星寶刀比七星寶刀多一星,應該能增加刺殺的勝算,於是向王允借八星寶刀。(杜撰)


1、八星寶刀——BaxingSword

package com.demo.factory.model.object;

import com.demo.factory.model.AbstractSword;

/**
 * Created by 麗傑 on 2017/6/3.
 */
public class BaxingSword extends AbstractSword{
    /**
     * 構造方法設置寶刀的名稱
     */
    public BaxingSword(){
        this.setName("八星寶刀");
    }
}

2、具體寶刀工廠(生產八星寶刀)——Caocao2

package com.demo.factory;

import com.demo.factory.itf.ISwordFactory;
import com.demo.factory.model.AbstractSword;
import com.demo.factory.model.object.BaxingSword;

/**
 * Created by 麗傑 on 2017/6/3.
 */
public class Caocao2 implements ISwordFactory{
    //生產八星寶刀
    public AbstractSword createSword(){
        return new BaxingSword();
    }
}

3、主應用程序——MainApp

package com.demo;

import com.demo.factory.Caocao;
import com.demo.factory.Caocao2;
import com.demo.factory.model.AbstractSword;
import com.demo.factory.itf.ISwordFactory;

/**
 * Created by 麗傑 on 2017/6/3.
 */
public class MainApp {

    public static void main(String[] args){
        //創建曹操實例對象(返回使用接口類型ISwordFactory)
        // ISwordFactory swordFactory = new Caocao();
        ISwordFactory swordFactory = new Caocao2();
        //獲得寶刀實例——八星寶刀c
        AbstractSword sword = swordFactory.createSword();
        //刺殺董卓
        System.out.print("曹操使用"+sword.getName()+"刺殺董卓!");
    }
}

4、運行效果



【小結】


1、工廠方法模式

   定義一個創建產品對象的工廠接口,讓子類決定實例化哪一種實例對象,也就是將實際創建實例對象的工作推遲到子類當中,核心工廠類不再負責具體產品的創建。


2、設計模式

(1)“開-閉”原則:對擴展開放,對修改關閉。

(2)依賴倒置原則:不論工廠還是產品都應該依賴於抽象,而不是具體的實現類。


3、工廠方法模式的使用場合

(1)當子類型可能會有很多,以後需要不斷增添不同的子類實現時;

(2)當一個系統尚在框架設計階段,還不知道將來需要實例化實例化哪些具體類時;

(3)系統設計之初不需要具體對象的概念(或者說沒有具體對象的概念)。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章