java23種設計模式—— 1、設計模式介紹
java23種設計模式—— 2、單例模式
java23種設計模式——3、工廠模式
java23種設計模式——4、原型模式
java23種設計模式——5、建造者模式
java23種設計模式——6、適配器模式java
工廠模式是咱們最經常使用的實例化對象模式了,是用工廠方法代替new操做的一種模式。著名的Jive論壇 ,就大量使用了工廠模式,工廠模式在Java程序系統能夠說是隨處可見。由於工廠模式就至關於建立實例對象的new,咱們常常要根據類Class生成實例對象,如A a=new A() 工廠模式也是用來建立實例對象的,因此之後new時就要多個心眼,是否能夠考慮使用工廠模式,雖然這樣作,可能多作一些工做,但會給你係統帶來更大的可擴展性和儘可能少的修改量。(百度百科)
工廠模式又分爲:git
屬於建立型模式,又叫作靜態工廠方法模式,不屬於23種GOF設計模式之一。是由一個工廠對象決定建立出哪種產品類的實例。違背「開放 - 關閉原則」,一旦添加新產品就不得不修改工廠類的邏輯,這樣就會形成工廠邏輯過於複雜。github
假設如今有一家餐館設計模式
public interface Restaurant { public void cook(); }
餐館有兩種菜品:紅燒肉和雞蛋羹bash
//雞蛋羹 public class Egg implements Restaurant { @Override public void cook() { System.out.println("雞蛋羹作好了"); } }
//紅燒肉 public class Meet implements Restaurant{ @Override public void cook() { System.out.println("紅燒肉作好了"); } }
餐館裏有服務員,來負責向後廚傳達客人的需求iphone
public class Waiter { //一樣能夠定義常量而後經過switch語句來實現 public static Restaurant getFood(String orderType) { Restaurant restaurant = null; if(orderType.equals("紅燒肉")){ restaurant = new Meet(); }else if (orderType.equals("雞蛋羹")){ restaurant = new Egg(); } return restaurant; } }
如今顧客來了,要點一份紅燒肉,就只須要和服務員說就行ide
public class Customer { public static void main(String[] args) { Restaurant restaurant = Waiter.getFood("紅燒肉"); restaurant.cook(); } }
輸出測試
紅燒肉作好了
經過以上方法,的確實現了 提供建立實例的功能,而無需關心具體實現。可是咱們不難發現,這種方法的擴展性不好,若是餐館新出了一款菜品,還須要咱們在服務員方法裏修改。這使得當餐館的菜品不少時,工廠方法代碼邏輯將會很是複雜優化
工廠方法模式,又稱工廠模式、多態工廠模式和虛擬構造器模式,經過定義工廠父類負責定義建立對象的公共接口,而子類則負責生成具體的對象。是在工廠模式家族中是用的最多模式,通常項目中存在最多的就是這個模式。是對簡單工廠模式的一個優化,讓每一個對象都有一個與之對應的工廠。
這裏咱們接着用上面的例子,假設這家餐廳的生意很是好,因此餐館的老闆把餐館全部負責點餐的服務員都辭退了,取而代之的是添加了一個收銀臺,而後讓每一個廚師只負責作同樣菜。這樣客人只須要和收銀臺說要求就好了。
這裏咱們接着用上面的類。除去服務員Waiter類
新建Cashier接口
/** * @author codermy * @createTime 2020/6/15 */ public interface Cashier { public Restaurant getFood(); }
而後給每個菜品新建一個工廠類
EggCooker
/** * @author codermy * @createTime 2020/6/15 */ public class EggCooker implements Cashier { @Override public Restaurant getFood() { return new Egg(); } }
MeetCooker
/** * @author codermy * @createTime 2020/6/15 */ public class MeetCooker implements Cashier{ @Override public Restaurant getFood() { return new Meet(); } }
而後顧客點單隻須要在收銀臺,餐廳的系統會自動將信息傳遞給相應的廚師,對應的廚師就能在餐館中把菜作好
/** * @author codermy * @createTime 2020/6/15 * 消費者 */ public class Customer { public static void main(String[] args) { Cashier order = new EggCooker(); Restaurant food = order.getFood(); food.cook(); } }
輸出結果
雞蛋羹作好了
工廠方法模式解決了簡單工廠模式不符合的開閉原則,當添加一個菜品時,只須要再僱傭一個廚師就行(從現實角度看,老闆有點虧哦)。可是這也增長了系統的複雜度(菜越多,廚師就越多,這哪家餐館頂的住)
這個模式解決了每一個工廠只能建立一類產品(工廠方法模式)的問題
這裏用餐館的例子不太形象,不是很容易理解,強行舉例可能會和上面的方法弄混,我本身繞了好一會,因此咱們換一個例子。
如今咱們人手不離手機,咱們假設手機有以下幾個功能
//手機產品接口 public interface IphoneProduct { void callup();//打電話 void sendSms();//發短信 }
每一個人家裏又都有路由器,路由器有以下功能
//路由器產品接口 public interface IRouterProduct { void openwifi();//開啓wifi void setting();//設置wifi }
而後如今有一個抽象產品工廠,是來生產這兩樣產品的,假設生產手機和路由器的方法是同樣的,只是須要加上廠商信息
//抽象產品工廠 public interface IProductFactory { //生產手機 IphoneProduct iphoneProduct(); //生產路由器 IRouterProduct iRouterProduct(); }
如今有兩家廠商,小米和華爲工廠,能夠生產手機和路由器,他們兩家廠商分別由兩條產業線來作手機和路由器
//小米手機 public class XiaomiPhone implements IphoneProduct{ @Override public void callup() { System.out.println("用小米手機打電話"); } @Override public void sendSms() { System.out.println("用小米手機發短信"); } }
//小米路由器 public class XiaomiRouter implements IRouterProduct { @Override public void openwifi() { System.out.println("打開小米wifi"); } @Override public void setting() { System.out.println("設置小米wifi"); } }
//小米廠商 public class XiaomiFactory implements IProductFactory { @Override public IphoneProduct iphoneProduct() { return new XiaomiPhone(); } @Override public IRouterProduct iRouterProduct() { return new XiaomiRouter(); } }
//華爲手機 public class HuaweiPhone implements IphoneProduct { @Override public void callup() { System.out.println("用華爲手機打電話"); } @Override public void sendSms() { System.out.println("用華爲手機發短信"); } }
//華爲路由器 public class HuaweiRouter implements IRouterProduct { @Override public void openwifi() { System.out.println("打開華爲wifi"); } @Override public void setting() { System.out.println("設置華爲wifi"); } }
//華爲工廠 public class HuaweiFactory implements IProductFactory { @Override public IphoneProduct iphoneProduct() { return new HuaweiPhone(); } @Override public IRouterProduct iRouterProduct() { return new HuaweiRouter(); } }
消費者類
//消費者/測試類 public class Customer { public static void main(String[] args) { System.out.println("==============小米產品================="); XiaomiFactory xiaomiFactory = new XiaomiFactory();//新建一個小米工廠 IphoneProduct xiaomiiphoneProduct = xiaomiFactory.iphoneProduct();//小米工廠開始生產小米手機 xiaomiiphoneProduct.callup();//測試小米手機打電話功能 IRouterProduct xiaomiiRouterProduct = xiaomiFactory.iRouterProduct();//小米工廠開始生產小米路由器 xiaomiiRouterProduct.openwifi();//測試小米路由器打開wifi功能 System.out.println("==============華爲產品================="); HuaweiFactory huaweiFactory = new HuaweiFactory(); IphoneProduct huaweiiphoneProduct1 = huaweiFactory.iphoneProduct(); huaweiiphoneProduct1.callup(); IRouterProduct huaweiiRouterProduct = huaweiFactory.iRouterProduct(); huaweiiRouterProduct.openwifi(); } }
輸出
==============小米產品================= 用小米手機打電話 打開小米wifi ==============華爲產品================= 用華爲手機打電話 打開華爲wifi
抽象工廠模式相較於以上兩種模式難以理解一些。這裏提供另外一種寫法比較好理解,來自Guide哥的博客(如下全部內容)
不知道你們玩過穿越火線或者吃雞這類遊戲了嗎,遊戲中存在各類槍。咱們假設如今存在AK、M4A1兩類槍,每一種槍對應一種子彈。咱們如今這樣考慮生產AK的工廠能夠順便生產AK使用的子彈,生產M4A1的工廠能夠順便生產M4A1使用的子彈。(AK工廠生產AK系列產品包括子彈啊,AK槍的類型啊這些,M4A1工廠同理)
————————————————
(1)建立相關接口:
槍
public interface Gun { public void shooting(); }
子彈
public interface Bullet { public void load(); }
(2)建立接口對應實現類:
AK類
public class AK implements Gun{ @Override public void shooting() { System.out.println("shooting with AK"); } }
M4A1類
public class M4A1 implements Gun { @Override public void shooting() { System.out.println("shooting with M4A1"); } }
AK子彈類
public class AK_Bullet implements Bullet { @Override public void load() { System.out.println("Load bullets with AK"); } }
M4A1子彈類
public class M4A1_Bullet implements Bullet { @Override public void load() { System.out.println("Load bullets with M4A1"); } }
(3)建立工廠接口
public interface Factory { public Gun produceGun(); public Bullet produceBullet(); }
(4)建立具體工廠
生產AK和AK子彈的工廠
public class AK_Factory implements Factory{ @Override public Gun produceGun() { return new AK(); } @Override public Bullet produceBullet() { return new AK_Bullet(); } }
生產M4A1和M4A1子彈的工廠
public class M4A1_Factory implements Factory{ @Override public Gun produceGun() { return new M4A1(); } @Override public Bullet produceBullet() { return new M4A1_Bullet(); } }
(5)測試
public class Test { public static void main(String[] args) { Factory factory; Gun gun; Bullet bullet; factory =new AK_Factory(); bullet=factory.produceBullet(); bullet.load(); gun=factory.produceGun(); gun.shooting(); } }
輸出結果:
Load bullets with AK shooting with AK