設計模式--工廠模式(一個關於工廠的故事)

今天在網上看到了一篇關於工廠模式的文章,看起來很是簡單易懂,就按作者的思路重新寫了一遍加深對工廠模式的理解。作爲低頭一族的一員虎將,接下來我也用我們最常用的手機作爲案例。做個例子,手機主要由電池、顯示屏、手機主板、手機外殼組成。

1.先定義手機實體,手機由電池、顯示屏、主板、外殼組成

package com.factory;
/**
 * 描述:手機實體:手機由電池、顯示屏、主板、外殼組成
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:30:28
 * 版本:1.0
 */
public class Phone {

    private String battry;
    private String display;
    private String matherBorad;
    private String shell;
    public String getBattry() {
        return battry;
    }
    public void setBattry(String battry) {
        this.battry = battry;
    }
    public String getDisplay() {
        return display;
    }
    public void setDisplay(String display) {
        this.display = display;
    }
    public String getMatherBorad() {
        return matherBorad;
    }
    public void setMatherBorad(String matherBorad) {
        this.matherBorad = matherBorad;
    }
    public String getShell() {
        return shell;
    }
    public void setShell(String shell) {
        this.shell = shell;
    }
    @Override
    public String toString() {
        return "Phone [battry=" + battry + ", display=" + display
                + ", matherBorad=" + matherBorad + ", shell=" + shell
                + ", getBattry()=" + getBattry() + ", getDisplay()="
                + getDisplay() + ", getMatherBorad()=" + getMatherBorad()
                + ", getShell()=" + getShell() + ", getClass()=" + getClass()
                + ", hashCode()=" + hashCode() + ", toString()="
                + super.toString() + "]";
    }
}

2.定義一個專門用來生產電池的接口

package com.factory;
/**
 * 描述:生產電池的概念
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:25:18
 * 版本:1.0
 */
public interface IBattery {
    //生產電池
    public String crateBattery();
}

3.定義一個專門生產手機屏幕的接口

package com.factory;
/**
 * 描述:顯示屏生產概念
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:27:04
 * 版本:1.0
 */
public interface IDisplay {
    /**生產顯示屏*/
    public String createDisplay();
}

4.定義一個專門生產手機主板的接口

package com.factory;
/**
 * 描述:手機主板生產概念
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:28:21
 * 版本:1.0
 */
public interface IMatherBorad {
    /**生產手機主板*/
    public String createMatherBorad();
}

5.定義一個專門生產手機外殼的接口

package com.factory;
/**
 * 描述:手機殼生產概念
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:29:06
 * 版本:1.0
 */
public interface IShell {
    /**生產手機外殼*/
    public String createShell();
}

6.定義一個獲取手機電池、顯示屏、主板、外殼的接口。我們生產手機的時候總要有原材料吧,要從各種零件的工廠中獲取原材料啊。

package com.factory;
/**
 * 描述:手機原料工廠
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:32:16
 * 版本:1.0
 */
public interface IFactory {

    /**電池*/
    public IBattery IcreateBattry();
    /**顯示屏*/
    public IDisplay IcreateDisplay();
    /**主板*/
    public IMatherBorad IcreateMatherBorad();
    /**外殼*/
    public IShell IcreateShell();

}

我們有了手機的各種零件的時候,要組裝起來才能成爲真正的手機。不然零件永遠只是零件。(這讓我想起了北朝鮮,研究核武器,研究遠程導彈,研究衛星。日本爲什麼抵制朝鮮把衛星發射到外空,因爲發射衛星跟核彈的原理是一樣的,在火箭上放衛星那就是一個衛星設備,在火箭上放一顆核彈,那就是一個武器。朝鮮說是發射衛星,突然把衛星一換就呵呵噠了)。好了,言歸正傳我們需要一個組裝手機的概念。

7.定義一個組裝手機的接口

package com.factory;
/**
 * 描述:手機組裝概念
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:34:57
 * 版本:1.0
 */
public interface IAssemblyPlant {

    /**組裝手機*/
    public Phone assemblyPlant();

}

世界上都是先有了生產的概念,生產的技術,然後纔會有專門生產這個產品的工具。上述聲明的接口就相當於世界上出現了生產手機電池、顯示屏、主板、外殼的概念了。至於用什麼技術去生產,這就是生產工廠的事情了。
時間一天天過去,好了,我們終於有了生產電池、顯示屏、主板、外殼這門技術了,然後我們紛紛建立工廠。這時候OPPO說,我也要製造手機,那好,手機需要什麼零件我們就建什麼工廠,就這樣:OPPO電池工廠、OPPO顯示屏工廠、OPPO主板工廠、OPPO外殼工廠建立起來了。

8.OPPO電池工廠(根據概念–>技術–>產品)

package com.factory;
/**
 * 描述:OPPO電池工廠
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:26:24
 * 版本:1.0
 */
public class OPPOBattery implements IBattery{

    /**
     * 生產OPPO的電池
     * @return 電池產品
     * */
    @Override
    public String crateBattery() {
        // TODO Auto-generated method stub
        return "OPPO手機電池";
    }

}

9.OPPO顯示屏工廠(概念–>技術–>產品)

package com.factory;
/**
 * 描述:OPPO顯示屏工廠
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:27:44
 * 版本:1.0
 */
public class OPPODisplay implements IDisplay{


    /**
     * 專門生產OPPO的顯示屏
     * @return 顯示屏產品
     * */
    @Override
    public String createDisplay() {
        // TODO Auto-generated method stub
        return "OPPO手機顯示屏";
    }

}

10.OPPO主板工廠(概念–>技術–>產品)

package com.factory;
/**
 * 描述:OPPO手機主板
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:38:12
 * 版本:1.0
 */
public class OPPOMatherBorad implements IMatherBorad{


    /**
     * 專門生產OPPO手機主板
     * @return 手機主板產品
     * */
    @Override
    public String createMatherBorad() {
        // TODO Auto-generated method stub
        return "OPPO手機主板";
    }

}

11.OPPO外殼工廠(概念–>技術–>產品)

package com.factory;
/**
 * 描述:OPPO手機殼工廠
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:29:36
 * 版本:1.0
 */
public class OPPOShell implements IShell{

    /**
     * 專門生產OPPO外殼
     * @return 手機外殼產品
     * */
    @Override
    public String createShell() {
        // TODO Auto-generated method stub
        return "OPPO手機外殼";
    }

}

OPPO真是牛逼,上來就是幹,幾天就把電池廠、顯示屏廠、主板廠、外殼廠建好並大規模生產了。市場不等人啊,各個工廠的零件出來了,得趕緊把這些零件收集起來,然後對零件進行組裝。是的,市場不等人,趕緊件一個收集零件的工廠和一個組裝零件的工廠吧。

12.建立蒐集零件的工廠

package com.phone;

import com.factory.IBattery;
import com.factory.IDisplay;
import com.factory.IFactory;
import com.factory.IMatherBorad;
import com.factory.IShell;
import com.factory.OPPOBattery;
import com.factory.OPPODisplay;
import com.factory.OPPOMatherBorad;
import com.factory.OPPOShell;

/**
 * 描述:OPPO手機原料廠
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:36:29
 * 版本:1.0
 */
public class OPPOFactory implements IFactory{


    /**
     * 作爲一個有逼格的OPPO收集廠,我只要OPPO電池
     * @return OPPOBattery:OPPO電池
     * */
    @Override
    public IBattery IcreateBattry() {
        // TODO Auto-generated method stub
        return new OPPOBattery();
    }

    /**
     * 作爲一個有逼格的OPPO收集廠,我只要OPPO顯示屏
     * @return OPPODisplay:OPPO顯示屏
     * */
    @Override
    public IDisplay IcreateDisplay() {
        // TODO Auto-generated method stub
        return new OPPODisplay();
    }

    /**
     * 作爲一個有逼格的OPPO收集廠,我只要OPPO主板
     * @return OPPOMatherBorad:OPPO主板
     * */
    @Override
    public IMatherBorad IcreateMatherBorad() {
        // TODO Auto-generated method stub
        return new OPPOMatherBorad();
    }

    /**
     * 作爲一個有逼格的OPPO收集廠,我只要OPPO外殼
     * @return OPPOShell:OPPO外殼
     * */
    @Override
    public IShell IcreateShell() {
        // TODO Auto-generated method stub
        return new OPPOShell();
    }

}

13.建立一個OPPO組裝工廠。默認(無參構造方法)情況下我們組裝出來的是OPPO手機,但是爲了業務需要,爲了生活,我們也乾點私活吧,咱有時間也組裝幾臺其他的手機吧。(有參構造方法)

package com.phone;

import com.factory.IAssemblyPlant;
import com.factory.IFactory;
import com.factory.Phone;

/**
 * 描述:OPPO手機組裝廠(OPPO手機組裝廠組裝出來的手機不一定就是OPPO手機)
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:39:21
 * 版本:1.0
 */
public class OPPOAssemblyPlant implements IAssemblyPlant{

    private IFactory materisFactotry;//手機原料(任意類型的手機原料)

    //組裝OPPO手機
    public OPPOAssemblyPlant(){
        this.materisFactotry=new OPPOFactory();
    }

    //OPPO手機裝配廠幹私活:組裝其他類型手機(山寨)
    public OPPOAssemblyPlant(IFactory iFactory){
        this.materisFactotry=iFactory;
    }


    //把原材料的電池、顯示屏、主板、外殼組裝成一部有逼格的手機
    @Override
    public Phone assemblyPlant() {
        // TODO Auto-generated method stub
        Phone phone=new Phone();
        phone.setBattry(materisFactotry.IcreateBattry().crateBattery());
        phone.setDisplay(materisFactotry.IcreateDisplay().createDisplay());
        phone.setMatherBorad(materisFactotry.IcreateMatherBorad().createMatherBorad());
        phone.setShell(materisFactotry.IcreateShell().createShell());
        return phone;
    }

}

牛逼了我的哥,組裝工廠能把組裝出一部真正的手機了。等你直接使用new Phone()來生成一個手機的時候,牛逼如我可以用OPPOAssemblyPlant(組裝工廠)的assemblyPlant()來組裝出屬於OPPO的手機了。

package com;

import com.factory.Phone;
import com.phone.OPPOAssemblyPlant;

/**
 * 描述:
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:24:56
 * 版本:1.0
 */
public class Main {

    public static void main(String[] args) {
        OPPOAssemblyPlant oppoAssemblyPlant=new OPPOAssemblyPlant();
        Phone phone=oppoAssemblyPlant.assemblyPlant();
        System.out.println(phone);
    }

}

生產結果如下:
這裏寫圖片描述

就這樣OPPO手機終於生產完成並投入市場了。半年過去了,市場上人人反饋這個OPPO手機充電兩小時,通話五分鐘。這就尷尬了。正好,市場上有一個公司建立了NOkia手機電池工廠,能充電五分鐘,通話兩小時。

14.市場上面的NOkia電池工廠

package com.factory;
/**
 * 描述:NOkia電池工廠,電量充足,正所謂:裝逼用Nokia,裝了還能再裝
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午3:27:28
 * 版本:1.0
 */
public class NOkiaBattery implements IBattery{

    @Override
    public String crateBattery() {
        // TODO Auto-generated method stub
        return "NOkia電池";
    }

}

這時候OPPO決定,我們OPPO2.0使用NOkia電池吧。然後董事長跟組裝廠廠長說,你們裝電池的時候裝NOkia的吧。組裝廠廠長:尼瑪,關我鳥事,我tm裝電池的時候纔不看這個是OPPO的還是NOkia的,你還是跟OPPO原材料廠廠長說吧,讓他蒐集材料的時候把去買NOkia的電池吧。但是有一點,原材料廠別把電池的接口給我換了,不管OPPO的還是NOkia的,電池的接口都要一樣。
就這樣組裝廠把這個皮球踢給了原材料廠,自己什麼都沒有改變,該吃的吃該喝的喝。

15.原材料廠蒐集材料的時候把OPPO電池換成了NOkia電池

package com.phone;

import com.factory.IBattery;
import com.factory.IDisplay;
import com.factory.IFactory;
import com.factory.IMatherBorad;
import com.factory.IShell;
import com.factory.NOkiaBattery;
import com.factory.OPPOBattery;
import com.factory.OPPODisplay;
import com.factory.OPPOMatherBorad;
import com.factory.OPPOShell;

/**
 * 描述:OPPO手機原料廠
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:36:29
 * 版本:1.0
 */
public class OPPOFactory implements IFactory{


    /**
     * 我要的是 NOkia電池
     * @return NOkiaBattery:NOkia電池
     * */
    @Override
    public IBattery IcreateBattry() {
        // TODO Auto-generated method stub
        return new NOkiaBattery();
    }

    /**
     * 作爲一個有逼格的OPPO收集廠,我只要OPPO顯示屏
     * @return OPPODisplay:OPPO顯示屏
     * */
    @Override
    public IDisplay IcreateDisplay() {
        // TODO Auto-generated method stub
        return new OPPODisplay();
    }

    /**
     * 作爲一個有逼格的OPPO收集廠,我只要OPPO主板
     * @return OPPOMatherBorad:OPPO主板
     * */
    @Override
    public IMatherBorad IcreateMatherBorad() {
        // TODO Auto-generated method stub
        return new OPPOMatherBorad();
    }

    /**
     * 作爲一個有逼格的OPPO收集廠,我只要OPPO外殼
     * @return OPPOShell:OPPO外殼
     * */
    @Override
    public IShell IcreateShell() {
        // TODO Auto-generated method stub
        return new OPPOShell();
    }

}

對比之前的OPPO原材料廠看看,我們的電池變量。

這次的變革中組裝廠什麼也沒變,看看他們組裝出來的手機是什麼樣的吧。

package com;

import com.factory.Phone;
import com.phone.OPPOAssemblyPlant;

/**
 * 描述:
 * 作者:Linxz
 * 郵箱:[email protected]
 * 時間: 2017-3-25 下午12:24:56
 * 版本:1.0
 */
public class Main {

    public static void main(String[] args) {
        OPPOAssemblyPlant oppoAssemblyPlant=new OPPOAssemblyPlant();
        Phone phone=oppoAssemblyPlant.assemblyPlant();
        System.out.println(phone);
    }

}

結果如下:
這裏寫圖片描述

董事會一看,還真tm邪門,組裝廠還組裝出來的OPPO手機的電池還真的是NOkia的。好了,市場不等人啊,衝他一下子。這次可以充電五分鐘通話兩小時了。

注:本故事純屬虛構(改編)
原文出處

發佈了38 篇原創文章 · 獲贊 17 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章