工廠模式

靜態(tài)工廠
在最早的《DesignPattern》這本書中 靜態(tài)工廠是沒有的 工廠系列就兩個(gè)模式 工廠方法和抽象工廠,但是也有人說靜態(tài)工廠是工廠模式

什么是工廠历筝?
1.任何可以產(chǎn)生(new)對象的方法或類友鼻,都可以稱之為工廠
2.看到1個(gè)方法 它的返回值return是1個(gè)對象 就可以稱之為1個(gè)工廠

所以單例也是一種工廠傻昙,單例模式的 getInstance 就是拿到1個(gè)對象 所以有人把單例模式 稱為靜態(tài)工廠

為什么要工廠? 我們已經(jīng)可以new產(chǎn)生對象了彩扔,為什么還要工廠妆档?
工廠可以靈活控制生產(chǎn)過程,可以加權(quán)限虫碉、修飾decorate贾惦、日志log等

我們先寫1個(gè)類 Car

public class Car {
    public void go() {
        System.out.println("Car go wuwuwuwuwu.....");
    }
}

然后我們再創(chuàng)建1個(gè)Main類 new出來1個(gè)Car

public class Main {
    public static void main(String[] args) {
        Car c = new Car();
        c.go();
    }
}
執(zhí)行main方法

現(xiàn)在開的是Car車 我明天想開Plane飛機(jī)怎么辦? 可以定制交通工具(實(shí)現(xiàn)類 )嗎敦捧?
我們當(dāng)然可以再創(chuàng)建1個(gè)Plane飛機(jī)類须板,然后main方法去創(chuàng)建1個(gè)飛機(jī)

public class Plane {
    public void go(){
        System.out.println("Plane fly xixixixixixixi....");
    }
}
public class Main {
    public static void main(String[] args) {
//        Car c = new Car();
//        c.go();
        Plane p = new Plane();
        p.go();
    }
}

如果我以后想開火車Train,船Boat等等兢卵?難道還是像這樣 1個(gè)1個(gè)擴(kuò)展嗎习瑰?代碼太多了,既要新建1個(gè)類秽荤,還要修改main方法里的內(nèi)容甜奄,我想少點(diǎn)柠横,怎么辦?
我們可以創(chuàng)建1個(gè)接口Moveable ,其他的所有交通工具去實(shí)現(xiàn)這個(gè)接口

public interface Moveable {
    void go();
}
public class Plane implements Moveable{
    public void go(){
        System.out.println("Plane fly xixixixixixixi....");
    }
}
public class Car implements Moveable{
    public void go() {
        System.out.println("Car go wuwuwuwuwu.....");
    }
}

這樣main方法可以利用多態(tài)课兄,只用改new后面的類就行了牍氛,不管調(diào)用

public class Main {
    public static void main(String[] args) {
        Moveable m = new Plane();
        m.go();
    }
}

代碼只用修改1個(gè)地方,不用像第1種方法烟阐,要?jiǎng)h除修改至少2段

需求又來了搬俊,我想任意定制旅途過程 怎么辦?
實(shí)際中的應(yīng)用 我new 1個(gè)交通工具后 我要求你必須控制權(quán)限 那么我的代碼要修改在Plane類里 必須要來回的變曲饱;我可以把 產(chǎn)生對象的這個(gè)過程 不用new 我交給1個(gè)工廠方法
1.簡單工廠VehicleFatory
創(chuàng)建1個(gè)VehicleFactory類 里面有幾個(gè)方法 比如返回Car對象的 createCar()方法 在這個(gè)方法里面 我們可以對它進(jìn)行日志處理 權(quán)限處理等悠抹;而且VehicleFactory類除了 產(chǎn)生Car外 還可以產(chǎn)生Plane等

public class VehicleFactory {
    public Car createCar(){
        return new Car();
    }
    public Plane createPlane(){
        return new Plane();
    }
}

但是這種方法不太好 因?yàn)樗m然很簡單 但是可擴(kuò)展性不太好 當(dāng)我們新添加1種交通工具 火車train的時(shí)候 里面就要新添加新的createTrain方法 而且里面的 權(quán)限處理的操作也是寫死的

針對每個(gè)產(chǎn)品做1個(gè)工廠
對于Car來說 我加1個(gè)CarFactory類

public class CarFactory {
    public Car createCar(){
        System.out.println("a car created!");
        return new Car();
    }
}

如果我們想用CarFactory的話 main方法要這樣寫

public class Main {
    public static void main(String[] args) {
        Moveable m = new CarFactory().createCar();
        m.go();
    }
}
簡單工廠

想來個(gè)Plane的話 就寫個(gè)PlaneFactory().createPlane() 想來個(gè)broom的話 就寫個(gè)BroomFactory().createBroom()
但是問題來了 當(dāng)我們要添加一種新的交通工具的時(shí)候 我們首先得把它的工廠做出來PlaneFactory,broomFactory 接下來 我還要把代碼改一下 更麻煩
總結(jié)一下:任意定制交通工具扩淀,我們可以 繼承Moveable楔敌;任意定制生產(chǎn)過程,我們可以Moveable XXXFactory.create()

2.抽象工廠
因?yàn)榻谐橄蠊S驻谆,所以是任意定制產(chǎn)品一族(不只1種系列產(chǎn)品)卵凑,叫abstractFactory 更加抽象這個(gè)問題。
比如:現(xiàn)在是這樣的 胜臊,作為1個(gè)司機(jī) 我開著一輛車 車還在跑勺卢,然后這個(gè)司機(jī),他手里還持有1個(gè)武器AK47 就叫AK47類象对,他還可以吃一點(diǎn)面包Bread 有個(gè)面包類
AK47類可以開槍黑忱,Brand類可以打印品牌

public class AK47 {
    public void shoot(){
        System.out.println("tutututututu.....");
    }
}

public class Brand {
    public void printName(){
        System.out.println("wdm");
    }
}

那么這樣我就模擬了 很多類產(chǎn)品 Car,AK47,Bread ,其實(shí)這個(gè)是 產(chǎn)品簇的概念 我們有沒有一種方式 可以靈活的指定 來擴(kuò)展新的產(chǎn)品簇勒魔,比如現(xiàn)在我來一個(gè)人是魔法師 他騎的是掃帚Broom 吃的是蘑菇Mushroom 它的魔法棒MagicStick可以發(fā)電 這樣當(dāng)新的產(chǎn)品加進(jìn)來的時(shí)候 代碼不用改太多呢甫煞?
可以的 我們可以new 1個(gè)AbstractFactory. 這個(gè)抽象工廠 可以生產(chǎn) 1系列產(chǎn)品 他可以生產(chǎn)食物,武器,交通工具

public abstract class Food {
    abstract void printName();
}

public abstract class Weapon {
    abstract void shoot();
}

public abstract class Vehicle {
    abstract void go();
}

我們假設(shè) 這個(gè)抽象工廠會(huì)產(chǎn)生 3類產(chǎn)品;第1類是Food冠绢,第2類是Vehicle抚吠,第3類是Weapon,他們都可以返回對應(yīng)的對象弟胀,可以生成抽象的產(chǎn)品

public abstract class AbstractFactory {
    abstract Food createFood();
    abstract Vehicle createVehicle();
    abstract Weapon createWeapon();
}

然后我們讓所有的不同類別的產(chǎn)品 去繼承
現(xiàn)代人的工具簇就是 Weapon對應(yīng)AK47,Food對應(yīng)Bread楷力,Vehicle對應(yīng)Car

//現(xiàn)代人的工具包
public class Car extends Vehicle{
    public void go() {
        System.out.println("Car go wuwuwuwuwu.....");
    }
}

public class Brand extends Food{
    public void printName(){
        System.out.println("wdm");
    }
}

public class AK47 extends Weapon{
    public void shoot(){
        System.out.println("tutututututu.....");
    }
}

我們做1個(gè)現(xiàn)代工廠ModernFactory,幫我們?nèi)ドa(chǎn)這些東西孵户,而不必自己去new

public class ModernFactory extends AbstractFactory {
    @Override
    Food createFood() {
        return new Brand();
    }
    @Override
    Vehicle createVehicle() {
        return new Car();
    }
    @Override
    Weapon createWeapon() {
        return new AK47();
    }
}

魔法師的工具簇就是 Weapon對應(yīng)MagStick,Food對應(yīng)MushRoom萧朝,Vehicle對應(yīng)Broom

//魔法師的工具包
public class Broom extends Vehicle {
    public void go(){
        System.out.println("Broom flying shushushus....");
    }
}

public class MushRoom extends Food {
    public void printName(){
        System.out.println("毒蘑菇");
    }
}

public class MagicStick extends Weapon{
    public void shoot(){
        System.out.println("dian dian dian dian....");
    }
}

魔法師就是魔法工廠MagicFactory,幫我們?nèi)ドa(chǎn)這些東西

public class MagicFactory extends AbstractFactory{
    @Override
    Food createFood() {
        return new MushRoom();
    }
    @Override
    Vehicle createVehicle() {
        return new Broom();
    }
    @Override
    Weapon createWeapon() {
        return new MagicStick();
    }
}

現(xiàn)在延届,我們main方法里面代碼就簡單了
之間我們需要1個(gè)1個(gè)new

        Car c =new Car();
        c.go();
        AK47 w=new AK47();
        w.shoot();
        Bread b=new Bread();
        b.printName();

現(xiàn)在不需要了 直接調(diào)用現(xiàn)代工廠里的方法就行

AbstractFactory f = new ModernFactory();
Vehicle c = f.createVehicle();
Weapon w = f.createWeapon();
Food  b = f.createFood();

而且修改代碼恨少剪勿,你想改成 魔法世界工廠 你就把new 后面改一下 下面的都不用改 new MagicFactory(),同理方庭,火星世界 就改成火星一簇 寫個(gè)MarsFactory 去實(shí)現(xiàn)里面的火星武器厕吉,食物酱固,機(jī)器

注意:這個(gè)工廠里用的都是繼承,不是接口的實(shí)現(xiàn)头朱,因?yàn)楣S里的產(chǎn)生的食品一般是現(xiàn)實(shí)中存在的运悲,但是它不是具體的某個(gè)食物,所以用抽象類比較合適项钮,而接口更加側(cè)重于這個(gè)東西的屬性班眯,moveable表示它這個(gè)東西可以動(dòng),comparable表示這個(gè)東西可以比較烁巫,所以從語義上用抽象類更加合適署隘,形容詞用接口,名詞用抽象類

比較 工廠方法 和抽象工廠
工廠方法:在產(chǎn)品擴(kuò)展時(shí)亚隙,比較方便
有Car 有Food 有AK47 以后比如說 還有帽子等等 非常方便


普通工廠

抽象工廠:然后 在產(chǎn)品簇上擴(kuò)展比較方便 但是在產(chǎn)品上擴(kuò)展不好擴(kuò)展


抽象工廠

所以這個(gè)是兩個(gè)維度上的擴(kuò)展磁餐,1個(gè)是產(chǎn)品一簇維度上 偏于擴(kuò)展; 另一個(gè)是產(chǎn)品單一維度上 好擴(kuò)展 都有自己的局限性

總結(jié)一下:
簡單工廠vs靜態(tài)工廠vs工廠方法vs抽象工廠
簡單工廠:我們隨便1個(gè)方法 只要createCar什么東西 返回的是1個(gè)對象 那么它就是簡單工廠
靜態(tài)工廠:靜態(tài)的方法Static產(chǎn)生 比如單例的getInstance 就是1個(gè)靜態(tài)工廠
工廠方法FactoryMethod:產(chǎn)品維度上擴(kuò)展 很方便
抽象工廠:產(chǎn)品一簇進(jìn)行擴(kuò)展

我們經(jīng)嘲⑵可以用抽象工廠來完成一鍵風(fēng)格替換诊霹,比如1個(gè)人物,我可以換它的聲音渣淳,皮膚脾还,動(dòng)作等

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市入愧,隨后出現(xiàn)的幾起案子鄙漏,更是在濱河造成了極大的恐慌,老刑警劉巖棺蛛,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泥张,死亡現(xiàn)場離奇詭異,居然都是意外死亡鞠值,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門渗钉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來彤恶,“玉大人,你說我怎么就攤上這事鳄橘∩耄” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵瘫怜,是天一觀的道長术徊。 經(jīng)常有香客問我,道長鲸湃,這世上最難降的妖魔是什么赠涮? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任子寓,我火速辦了婚禮,結(jié)果婚禮上笋除,老公的妹妹穿的比我還像新娘斜友。我一直安慰自己,他們只是感情好垃它,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布鲜屏。 她就那樣靜靜地躺著,像睡著了一般国拇。 火紅的嫁衣襯著肌膚如雪洛史。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天酱吝,我揣著相機(jī)與錄音也殖,去河邊找鬼。 笑死掉瞳,一個(gè)胖子當(dāng)著我的面吹牛毕源,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播陕习,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼霎褐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了该镣?” 一聲冷哼從身側(cè)響起冻璃,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎损合,沒想到半個(gè)月后省艳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嫁审,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年跋炕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片律适。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辐烂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捂贿,到底是詐尸還是另有隱情纠修,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布厂僧,位于F島的核電站扣草,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜辰妙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一鹰祸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧上岗,春花似錦福荸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至呆瞻,卻和暖如春台夺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背痴脾。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工颤介, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赞赖。 一個(gè)月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓滚朵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親前域。 傳聞我的和親對象是個(gè)殘疾皇子辕近,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容