1. 程式人生 > >設計模式之工廠模式(Factory Pattern)

設計模式之工廠模式(Factory Pattern)

工廠模式(Factory Pattern)是 Java 中最常用的設計模式之一。

這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。

在工廠模式中,我們在建立物件時不會對客戶端暴露建立邏輯,並且是通過使用一個共同的介面來指向新建立的物件。

我這裡選擇生產手機的工廠作為模型物件。

一、分析生產手機的過程,形成要模擬的物件。

1、一部手機要被生產出來,首先要設計,備料,製造,測試,裝箱等幾步;
2、分析手機生產的過程,我們可以知道,備料,製造,測試,裝箱是在製造工廠完成,而設計過程一般是在手機公司自己設計;比如,小米公司、蘋果公司。
3、到這裡,實際上我們可以產生兩個物件,一個是手機物件,包括手機的屬性和設計過程,另一個是製造手機的工廠物件,包括手機的製造、測試、裝箱。


二、根據分析結果,實現兩個物件
1、工廠物件
工廠物件負責生產手機,因為一個工廠可以生產多種手機,所以,工廠物件裡面可以分為兩部分,一部分是相同同的生產部分,一部分是不同的生產部分;
同時,我們會有不同的工廠來生產手機,所以,我們把工廠方法抽象,讓具體的工廠子類去繼承;
/**
 * 工廠抽象類,方便於統一管理,標準生產
 * zhuyuehao
 * 2018/3/7下午2:31
 */
public abstract class AbstractPhotoFactory {
    //相同的部分,公共的邏輯
    public final Photo orderPhoto(String type){
        Photo photo;
        //例項化要生產的手機
        photo = createPhoto(type);
        if(photo==null){
            System.out.println("不能生產該手機!");
            System.out.println("-----------------------------------end");
            return null;
        }
        photo.prepare();
        photo.make();
        photo.test();
        photo.box();
        System.out.println("-----------------------------------end");
        return photo;
    }
    //不同的部分,生產不同手機
    /**
     * 生產手機
     * @return Photo
     */
    public abstract Photo createPhoto(String type);
}


/**
 * 富士康工廠
 * zhuyuehao
 * 2018/3/8上午11:24
 */
public class FoxconnFactory extends AbstractPhotoFactory {
    public Photo createPhoto(String type) {
        if("小米".equals(type)){
            return new XiaoMiPhoto();
        }else if ("華為".equals(type)){
            return new HuaWeiPhoto();
        }else if ("蘋果".equals(type)){
            return new ApplePhoto();
        }else return null;
    }
}


/**
 * 偉創力工廠
 * zhuyuehao
 * 2018/3/8上午11:24
 */
public class FlextronicsFactory extends AbstractPhotoFactory {
    public Photo createPhoto(String type) {
        if("小米".equals(type)){
            return new XiaoMiPhoto();
        }else if ("華為".equals(type)){
            return new HuaWeiPhoto();
        }else return null;
    }
}


2、手機物件
我們需要生產小米、華為、蘋果三款手機,我們可以定義三個手機物件,當然,因為手機物件有很多相同之處,所以,我們也可以用一個抽象的類作為父類;
/**
 * 手機的抽象類,父類
 * 包括手機的屬性,及生產手機的過程
 * zhuyuehao
 * 2018/3/7上午9:42
 */
public abstract class Photo {


    /**
     * 手機顏色
     */
    private String color;


    /**
     * 螢幕尺寸
     */
    private String screenSize;


    /**
     * 牌子名稱
     */
    private String sign;




    ArrayList toppings = new ArrayList();




    /**
     * 準備流程,物料準備
     */
    public void prepare(){
        System.out.println("Preparing:" + sign);
        System.out.println("Adding color:" + color);
        System.out.println("Adding screenSize:" + screenSize);
        /**
         * 子類擴充套件流程
         */
        for(int i=0;i<toppings.size();i++){
            System.out.println("Adding specific:" + toppings.get(i));
        }
    }


    /**
     * 製造
     */
    public void make(){
        System.out.println("Making...");
    }


    /**
     * 測試
     */
    public void test(){
        System.out.println("Testing...");
    }


    /**
     * 裝箱
     */
    public void box(){
        System.out.println("Place photo in official photo box");
    }






    public String getColor() {
        return color;
    }


    public void setColor(String color) {
        this.color = color;
    }


    public String getScreenSize() {
        return screenSize;
    }


    public void setScreenSize(String screenSize) {
        this.screenSize = screenSize;
    }


    public String getSign() {
        return sign;
    }


    public void setSign(String sign) {
        this.sign = sign;
    }


    @Override
    public String toString() {
        return "Photo{" +
                "color='" + color + '\'' +
                ", screenSize='" + screenSize + '\'' +
                ", sign='" + sign + '\'' +
                '}';
    }
}


/**
 * zhuyuehao
 * 2018/3/8上午11:01
 */
public class XiaoMiPhoto extends Photo {
    public XiaoMiPhoto() {
        setColor("black");
        setScreenSize("5.0");
        setSign("小米5");
        toppings.add("電池");
    }


    @Override
    public void test() {
        System.out.println("Test500 hours");
    }
}


/**
 * zhuyuehao
 * 2018/3/8上午11:20
 */
public class HuaWeiPhoto extends Photo {
    public HuaWeiPhoto() {
        setColor("yellow");
        setScreenSize("5.12");
        setSign("華為P10");
    }
}


/**
 * zhuyuehao
 * 2018/3/8上午11:20
 */
public class ApplePhoto extends Photo {
    public ApplePhoto() {
        setColor("white");
        setScreenSize("4.7");
        setSign("iphone X");
        toppings.add("Add IOS");
    }
}


三、測試
public class AbsFactoryTest {
    public static void main(String[] args) {
        //例項化一個富士康工廠
        AbstractPhotoFactory foxconnFactory = new FoxconnFactory();
        foxconnFactory.orderPhoto("小米");
        //富士康工廠生產蘋果手機
        foxconnFactory.orderPhoto("蘋果");
        //富士康工廠生產華為手機
        foxconnFactory.orderPhoto("華為");


        //例項化一個偉創力工廠
        AbstractPhotoFactory flextronicsFactory = new FlextronicsFactory();
        flextronicsFactory.orderPhoto("小米");
        //偉創力工廠生產蘋果手機
        flextronicsFactory.orderPhoto("蘋果");
        //偉創力工廠生產華為手機
        flextronicsFactory.orderPhoto("華為");
    }
}


執行結果:
Preparing:小米5
Adding color:black
Adding screenSize:5.0
Adding specific:電池
Making...
Test500 hours
Place photo in official photo box
-----------------------------------end
Preparing:iphone X
Adding color:white
Adding screenSize:4.7
Adding specific:Add IOS
Making...
Testing...
Place photo in official photo box
-----------------------------------end
Preparing:華為P10
Adding color:yellow
Adding screenSize:5.12
Making...
Testing...
Place photo in official photo box
-----------------------------------end
Preparing:小米5
Adding color:black
Adding screenSize:5.0
Adding specific:電池
Making...
Test500 hours
Place photo in official photo box
-----------------------------------end
不能生產該手機!
-----------------------------------end
Preparing:華為P10
Adding color:yellow
Adding screenSize:5.12
Making...
Testing...
Place photo in official photo box
-----------------------------------end


四、總結
上面是對抽象工廠模式的簡單實現,通過抽象工廠,我們不需要知道工廠內部是如何做的,就可以得到我們想要的產品;

同時,通過抽象類的應用,當有新的工廠和新的手機時,可以很方便的擴充套件。