師父讓我來煉丹
話說,很久以前,武林中各大門派林立,百家爭鳴,忽然《九陰真經》再現江湖,各大門派各自暗中派出高手爭搶,都想獨吞《九陰真經》,習得神功,一統江湖。
闖蕩江湖,當然必備各種良藥防身,小帥師父在華山腳下的仙草藥房,生意忽然好了很多,各種丹藥銷量大增。
師父苦心研製的丹藥受到的武林人士的肯定,很是開心,其中的行軍丹,金創藥,黑玉斷續膏,號稱鎮店三寶。
訂單如雪花般飛來,師父命小帥在後院加班加點生產,但是由於各種特效藥製作工藝複雜,小帥和幾個夥計忙的團團轉。
客官要問煉丹的場所在何處?
說出來有點不好意思,就在藥房的後院。
藥品的生產代碼如下:
不用設計模式
藥品抽象類
abstract public class Drug {
/**
* 藥品名稱
*/
String name;
/**
* 功效
*/
String efficacy;
public void packing() {
System.out.println("打包藥品:" + name);
}
@Override
public String toString() {
// 藥丸的功效
StringBuffer display = new StringBuffer();
display.append("---- " + name + " 使用說明 ----\n");
display.append("具有功效:" + efficacy + "\n");
return display.toString();
}
}
具體藥品:行軍丹
public class XingJunDanDrug extends Drug{
public XingJunDanDrug() {
name = "行軍丹";
System.out.println("開始製作:祖傳祕法祕製七天");
System.out.println("製作完成-->行軍丹");
efficacy = "江湖中常見的療傷藥丸,尺寸小,便於攜帶,服用後見效快,恢復生命100點。";
}
}
具體藥品:金瘡藥
public class JinChuangYaoDrug extends Drug{
public JinChuangYaoDrug() {
name = "金瘡藥";
System.out.println("開始製作:祖傳祕法祕製七七四十九天");
System.out.println("製作完成-->金瘡藥");
efficacy = "聞名天下的佛門療傷奇藥,闖蕩江湖必備,加速癒合,服用後立即恢復生命500點。";
}
}
具體藥品:黑玉斷續膏
public class HeiYuDuanXuGaoDrug extends Drug{
public HeiYuDuanXuGaoDrug() {
name = "黑玉斷續膏";
System.out.println("開始製作:祖傳祕法祕製九九八十一天");
System.out.println("製作完成-->黑玉斷續膏");
efficacy = "傳說中的稀世祕藥,有再造之力,神奇無比,其價堪比黃金,服用後立即恢復生命2500點。";
}
}
仙草藥房
public class Drugstore {
/**
* 藥房接到訂單生產藥品
* @param type
* @return
*/
public Drug orderDrug(String type) {
Drug drug = null;
System.out.println("接到訂單:" + type);
// 生產藥品
if("行軍丹".equals(type)) {
drug = new XingJunDanDrug();
} else if("金瘡藥".equals(type)) {
drug = new JinChuangYaoDrug();
} else if("黑玉斷續膏".equals(type)) {
drug = new HeiYuDuanXuGaoDrug();
}
// 打包藥品
drug.packing();
return drug;
}
}
測試類
public class DrugstoreTest {
public static void main(String[] args) {
Drugstore drugstore = new Drugstore();
System.out.println("爲保證品質,本店所有藥品只接受預定:");
System.out.println();
// 藥房接到行軍丹訂單
Drug drug = drugstore.orderDrug("行軍丹");
System.out.println(drug);
// 藥房接到金瘡藥訂單
drug = drugstore.orderDrug("金瘡藥");
System.out.println(drug);
// 藥房接到黑玉斷續膏訂單
drug = drugstore.orderDrug("黑玉斷續膏");
System.out.println(drug);
}
}
測試結果
爲保證品質,本店所有藥品只接受預定:
接到訂單:行軍丹
開始製作:祖傳祕法祕製七天
製作完成-->行軍丹
打包藥品:行軍丹
---- 行軍丹 使用說明 ----
具有功效:江湖中常見的療傷藥丸,尺寸小,便於攜帶,服用後見效快,恢復生命100點。
接到訂單:金瘡藥
開始製作:祖傳祕法祕製七七四十九天
製作完成-->金瘡藥
打包藥品:金瘡藥
---- 金瘡藥 使用說明 ----
具有功效:聞名天下的佛門療傷奇藥,闖蕩江湖必備,加速癒合,服用後立即恢復生命500點。
接到訂單:黑玉斷續膏
開始製作:祖傳祕法祕製九九八十一天
製作完成-->黑玉斷續膏
打包藥品:黑玉斷續膏
---- 黑玉斷續膏 使用說明 ----
具有功效:傳說中的稀世祕藥,有再造之力,神奇無比,其價堪比黃金,服用後立即恢復生命2500點。
有什麼問題?
所有的原材料和設備都堆在後院,雜亂不堪,而且每種藥的生產工序和流程都不一樣,每一種藥品的生產設備都不一樣。
小帥和幾個夥計,終日奔波在不同的藥品生產設備之間,還要理清楚各種各樣的草藥,一不小心就弄亂了。
仙草店的生意越來越好,小帥和夥計很本忙不過來,藥品的產量卻越來越低了。
“有問題啊,藥房類直接依賴具體的藥品類,藥品類直接在藥房類中創建,藥房類和具體的藥品類高耦合,這違反了依賴倒置原則:要依賴抽象,不要依賴具體類。
還有,藥房既負責銷售又負責生產,增加了複雜性,功能不夠單一啊,這違反了單一職責原則”,有一天,師父忽然有感而發。
小帥在旁邊聽得一臉懵逼,感覺和師父不是同一個時代的人。
過了幾日,黑玉斷續膏的原料斷貨,停止生產,師父又開發了一款新藥,靈葫仙丹,恢復內力很有療效,深受各路武林人士喜愛,馬上加入生產。
“還是有問題啊,每停止生產或者新生產一款藥品,都要修改藥店的設備和原料,對店鋪影響很大啊“,有一天師父在院子裏打坐,若有所思的說,接着忽然冒出一句奇怪的話來:“這違反了開閉原則,應該對擴展開發,對修改封閉”,聽得小帥一頭霧水。
這一不小心就違反了三大設計原則:依賴倒置原則,單一職責原則,開閉原則。。。
這該如何是好?
小帥每日苦苦思索,始終不得要領,臉上多了幾分與年齡不相符的憂愁,再想下去,頭髮都要掉了,只好向師父請教。
師父微微一笑,心中早有對策。
沒過幾日,師父忽然決定在店鋪附近的山腳下建一個工廠,把原材料和設備都搬過去,專門生產藥品,店裏只負責銷售,讓銷售和生產分離開來。
“師父你要建一個工廠?”
“嗯,一個簡單的工廠。”
師父專門撥了一大筆銀兩,找了村裏最能幹的幾位壯士,幾個月後一個嶄新的工廠就建好了,小帥和夥計們都高高興興地搬了進去。
簡單工廠
簡單工廠的類圖如下:
(圖片來源:https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/simple_factory.html)
簡單工廠類
public class SimpleDrugFactory {
/**
* 生產藥品
* @param type
* @return
*/
public static Drug createDrug(String type) {
Drug drug = null;
// 生產藥品
if ("行軍丹".equals(type)) {
drug = new XingJunDanDrug();
} else if ("金瘡藥".equals(type)) {
drug = new JinChuangYaoDrug();
} else if ("黑玉斷續膏".equals(type)) {
drug = new HeiYuDuanXuGaoDrug();
} else if ("靈葫仙丹".equals(type)) {
drug = new LinHuXianDanDrug();
}
return drug;
}
}
新的仙草藥房
public class Drugstore {
/**
* 藥房接到訂單生產藥品
* @param type
* @return
*/
public Drug orderDrug(String type) {
Drug drug = null;
System.out.println("接到訂單:" + type);
// 通過工廠生產藥品
drug = SimpleDrugFactory.createDrug(type);
// 打包藥品
drug.packing();
return drug;
}
}
簡單工廠解決了什麼問題?
藥品的生產從藥房搬到了工廠裏,新增了一個簡單工廠類,修改了藥店裏生產藥品的代碼,除此之外,其他代碼都沒有變。
有了新的工廠,仙草藥店現在只負責銷售了,工廠專門負責生產藥品,這樣各自負責自己的職責,效率大大提高了。這就符合了單一職責原則。
簡單工廠使藥房類和具體的藥品類解耦,依賴了藥品抽象類,符合了依賴倒置原則。
什麼是依賴倒置原則?
依賴倒置原則:要依賴抽象,不要依賴具體類。
也就是說,不能讓高層組件依賴低層組件,不管高層還是低層組件都應該依賴於抽象。
聽不懂,太抽象對不對?
小帥也聽不懂啊,師父耐心的給他講解,還畫了一幅圖。。。
這裏的藥房就是高層組件,具體的丹藥就是低層組件,剛開始在藥房裏直接生產藥品,藥房(高層組件)依賴具體丹藥(低層組件)。
藥房(高層組件)和具體丹藥(低層組件)之間高耦合,這就是傳統的依賴關係。
爲什麼叫傳統的依賴關係呢?可能是因爲人們天然的認爲高層的組件都應該依賴底層的組件,這樣更符合人們的常識。
依賴倒置?有點反常識啊,但是在軟件設計中,這樣更有好處哦。
後面我們採用了簡單工廠模式,藥房(高層組件)依賴於藥品類(抽象),具體丹藥(低層組件)也依賴於(實現)藥品類(抽象),這就倒置了依賴。
藥房(高層組件)和具體丹藥(低層組件)之間實現瞭解耦,這樣就符合依賴倒置原則了!
原來如此,小帥恍然大悟。。。
還有什麼問題?
雖然把所有的生產設備都搬到簡單工廠裏了,但是隨着師父開發的新品越來越多,工廠也變得越來越大,越來越複雜。
簡單工廠模式有一組 if 分支判斷邏輯,每上一種新產品都要修改工廠的生產線,需要修改工廠類的代碼,還是違反了開閉原則,沒有對擴展開發,對修改封閉啊。
是不是應該用多態或其他設計模式來替代呢?實際上,如果 if 分支並不是很多,代碼中有 if 分支也是完全可以接受的。
不過,小帥看得更長遠,他覺得以後生產的丹藥會越來越多,一個工廠根本放不下那麼多生產設備。
他向師父提議:”要不,我們把大工廠拆分成一個個小工廠,每個工廠只生產一種藥品,這樣管理起來就簡單多了。“
師父年紀雖然大了,但是心態還是很年輕的,具有持續發展的戰略眼光,馬上採納了小帥的建議,建了很多小工廠,每個工廠只負責生產一種丹藥。
工廠模式
工廠方法模式(Factory Method Pattern)又稱爲工廠模式,定義一個創建對象的接口,讓其子類自己決定實例化哪一個工廠類,工廠模式使其創建過程延遲到子類進行。
工廠模式類圖如下:
(圖片來源:https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/factory_method.html)
工廠接口
public interface IDrugFactory {
/**
* 生產藥品
* @return
*/
Drug createDrug();
}
行軍丹工廠
public class XingJunDanDrugFactory implements IDrugFactory{
public Drug createDrug() {
return new XingJunDanDrug();
}
}
金瘡藥工廠
public class JinChuangYaoDrugFactory implements IDrugFactory {
public Drug createDrug() {
return new JinChuangYaoDrug();
}
}
黑玉斷續膏工廠
public class HeiYuDuanXuGaoDrugFactory implements IDrugFactory{
public Drug createDrug() {
return new HeiYuDuanXuGaoDrug();
}
}
新的仙草藥房
public class Drugstore {
/**
* 藥房接到訂單生產藥品
* @param type
* @return
*/
public Drug orderDrug(String type) {
IDrugFactory drugFactory = null;
Drug drug = null;
System.out.println("接到訂單:" + type);
// 獲取對應的工廠
if ("行軍丹".equals(type)) {
drugFactory = new XingJunDanDrugFactory();
} else if ("金瘡藥".equals(type)) {
drugFactory = new JinChuangYaoDrugFactory();
} else if ("黑玉斷續膏".equals(type)) {
drugFactory = new HeiYuDuanXuGaoDrugFactory();
} else if ("靈葫仙丹".equals(type)) {
drugFactory = new LinHuXianDanDrugFactory();
}
// 生產對應的藥品
drug = drugFactory.createDrug();
// 打包藥品
drug.packing();
return drug;
}
}
其他代碼都沒有變化,新的仙草藥房只要根據不同的藥品去不同的工廠拿貨就行了。
這樣以後新增一種丹藥,只要新增一個實現IDrugFactory 的工廠類就行了,不用修改工廠代碼,工廠方法模式比起簡單工廠模式更加符合開閉原則。
不過,應用多態或設計模式來替代 if 分支判斷邏輯,也並不是沒有任何缺點的,它雖然提高了代碼的擴展性,更加符合開閉原則,但也增加了類的個數,犧牲了代碼的可讀性。
現在工廠類裏的if判斷邏輯消除了,但是,if邏輯判斷,從簡單工廠類裏又移回藥房了。
if邏輯判斷轉了一圈,又回到了藥房類中,新增一個新工廠需要改動藥房類的代碼,這樣藥房類就不符合開閉原則了啊。
真是憂傷呢,改如何解決呢?
如何去掉if邏輯判斷
“可以再建一個生產工廠的工廠,然後用Map消除if邏輯判斷”,小帥靈光一現。
生產工廠的工廠
public class DrugFactoryMap {
private static final Map<String, IDrugFactory> cachedFactories = new HashMap<String, IDrugFactory>();
static {
cachedFactories.put("行軍丹", new XingJunDanDrugFactory());
cachedFactories.put("金瘡藥", new JinChuangYaoDrugFactory());
cachedFactories.put("黑玉斷續膏", new HeiYuDuanXuGaoDrugFactory());
cachedFactories.put("靈葫仙丹", new LinHuXianDanDrugFactory());
}
public static IDrugFactory getFactory(String type) {
if(type == null || type.isEmpty()) {
return null;
}
return cachedFactories.get(type);
}
}
藥房類直接從DrugFactoryMap類中取對應的工廠就行了,成功的把if邏輯判斷轉移到了DrugFactoryMap類的Map中了。
DrugFactoryMap類其實就上面的簡單工廠的另一種實現方式。
上面的方式就是簡單工廠+工廠模式啊。
我去,要建好多工廠啊。。。
抽象工廠模式
抽象工廠模式(Abstract Factory Pattern):提供一個創建一系列相關或相互依賴對象的接口,而無須指定它們具體的類。
抽象工廠類圖如下:
(圖片來源:https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/abstract_factory.html)
師父真是個很有上進心的人啊,平時這麼忙了,還廢寢忘食地開發新產品,你看,這幾個月師父又發明了新配方,在原來的行軍丹,金瘡藥,黑玉斷續膏中加入了祕製草藥和礦物質,使行軍丹,金瘡藥,黑玉斷續膏不僅能恢復生命值而且還能同時恢復內力!
這種神奇的超級藥丸,極其珍貴,只限量供應vip客戶。
仙草藥房在武林中的名號越來越響了。
但是,新品研發出來了,有一個問題,就是每種新的丹藥都要建一個對應的工廠啊,隨着藥品越來越多,工廠也越來越多,建工廠可是個燒錢的東西,慢慢得師父也覺得有點不妥。
小帥天天在各個工廠之間奔波,對工廠的運轉非常瞭解,他發現有些藥品的製造工藝有些相似之處。
例如:普通的行軍丹,金瘡藥和黑玉斷續膏,都用到了天山雪蓮和忘憂水,需要在八卦爐中提煉。
超級的行軍丹,金瘡藥和黑玉斷續膏,都採用了華山腳下的神祕礦物質,需要吸收日月精華,加上祕製草藥作爲藥引,才具有恢復內力的功效。
”不如,我們把普通的行軍丹,金瘡藥和黑玉斷續膏都集中在一個工廠裏生產,稱爲H系列,把同時具有恢復內力功效的行軍丹,金瘡藥和黑玉斷續膏放到另一個工廠裏生產,叫做S系列,如何?“
”如此甚好!“,師父大喜,立馬下令改造組合工廠,一個生產H系列產品,另一個生產S系列產品。
完整的代碼如下:
藥品抽象類
abstract public class Drug {
/**
* 藥品名稱
*/
String name;
/**
* 功效
*/
String efficacy;
public void packing() {
System.out.println("打包藥品:" + name);
}
@Override
public String toString() {
// 藥丸的功效
StringBuffer display = new StringBuffer();
display.append("---- " + name + " 使用說明 ----\n");
display.append("具有功效:" + efficacy + "\n");
return display.toString();
}
}
普通行軍丹
public class XingJunDanDrug extends Drug {
public XingJunDanDrug() {
name = "行軍丹";
System.out.println("開始製作:祖傳祕法祕製七天");
System.out.println("製作完成-->行軍丹");
efficacy = "江湖中常見的療傷藥丸,尺寸小,便於攜帶,服用後見效快,恢復生命100點。";
}
}
普通金瘡藥
public class JinChuangYaoDrug extends Drug {
public JinChuangYaoDrug() {
name = "金瘡藥";
System.out.println("開始製作:祖傳祕法祕製七七四十九天");
System.out.println("製作完成-->金瘡藥");
efficacy = "聞名天下的佛門療傷奇藥,闖蕩江湖必備,加速癒合,服用後立即恢復生命500點。";
}
}
普通黑玉斷續膏
public class HeiYuDuanXuGaoDrug extends Drug {
public HeiYuDuanXuGaoDrug() {
name = "黑玉斷續膏";
System.out.println("開始製作:祖傳祕法祕製九九八十一天");
System.out.println("製作完成-->黑玉斷續膏");
efficacy = "傳說中的稀世祕藥,有再造之力,神奇無比,其價堪比黃金,服用後立即恢復生命2500點。";
}
}
超級行軍丹
public class SuperXingJunDanDrug extends Drug {
public SuperXingJunDanDrug() {
name = "超級行軍丹";
System.out.println("開始製作:祖傳祕法祕製七天");
System.out.println("製作完成-->超級行軍丹");
efficacy = "江湖中常見的療傷藥丸,尺寸小,便於攜帶,服用後見效快,恢復生命100點,具備超級功效-->同時恢復50點內力。";
}
}
超級金瘡藥
public class SuperJinChuangYaoDrug extends Drug {
public SuperJinChuangYaoDrug() {
name = "超級金瘡藥";
System.out.println("開始製作:祖傳祕法祕製七七四十九天");
System.out.println("製作完成-->超級金瘡藥");
efficacy = "聞名天下的佛門療傷奇藥,闖蕩江湖必備,加速癒合,服用後立即恢復生命500點,具備超級功效-->同時恢復250點內力。";
}
}
超級黑玉斷續膏
public class SuperHeiYuDuanXuGaoDrug extends Drug {
public SuperHeiYuDuanXuGaoDrug() {
name = "超級黑玉斷續膏";
System.out.println("開始製作:祖傳祕法祕製九九八十一天");
System.out.println("製作完成-->超級黑玉斷續膏");
efficacy = "傳說中的稀世祕藥,有再造之力,神奇無比,其價堪比黃金,服用後立即恢復生命2500點,具備超級功效-->同時恢復1000點內力。";
}
}
抽象工廠
public interface IDrugFactory {
/**
* 生產藥品
* @return
*/
Drug createDrug(String type);
}
生產普通丹藥的工廠
public class NormalDrugFactory implements IDrugFactory {
/**
* 生產普通藥品
* @param type
* @return
*/
@Override
public Drug createDrug(String type) {
Drug drug = null;
// 生產藥品
if ("行軍丹".equals(type)) {
drug = new XingJunDanDrug();
} else if ("金瘡藥".equals(type)) {
drug = new JinChuangYaoDrug();
} else if ("黑玉斷續膏".equals(type)) {
drug = new HeiYuDuanXuGaoDrug();
}
return drug;
}
}
生產超級丹藥的工廠
public class SuperDrugFactory implements IDrugFactory{
/**
* 生產超級藥品
* @param type
* @return
*/
@Override
public Drug createDrug(String type) {
Drug drug = null;
// 生產超級藥品
if ("行軍丹".equals(type)) {
drug = new SuperXingJunDanDrug();
} else if ("金瘡藥".equals(type)) {
drug = new SuperJinChuangYaoDrug();
} else if ("黑玉斷續膏".equals(type)) {
drug = new SuperHeiYuDuanXuGaoDrug();
}
return drug;
}
}
藥房類
public class Drugstore {
/**
* 藥房接到訂單生產藥品
* @param type
* @return
*/
public Drug orderDrug(String type, boolean isVip) {
IDrugFactory drugFactory = null;
if(isVip) {
drugFactory = new SuperDrugFactory();
System.out.println("接到VIP訂單:" + type + " 切換超級工廠");
} else {
drugFactory = new NormalDrugFactory();
System.out.println("接到普通訂單:" + type + " 切換普通工廠");
}
// 通過工廠生產藥品
Drug drug = drugFactory.createDrug(type);
// 打包藥品
drug.packing();
return drug;
}
}
測試類
public class DrugstoreTest {
public static void main(String[] args) {
// 是否vip客戶
boolean isVip = false;
Drugstore drugstore = new Drugstore();
System.out.println("爲保證品質,本店所有藥品只接受預定:");
System.out.println();
// 藥房接到行軍丹訂單
Drug drug = drugstore.orderDrug("行軍丹", isVip);
System.out.println(drug);
// 藥房接到金瘡藥訂單
drug = drugstore.orderDrug("金瘡藥", isVip);
System.out.println(drug);
// 藥房接到黑玉斷續膏訂單
drug = drugstore.orderDrug("黑玉斷續膏", isVip);
System.out.println(drug);
}
}
測試結果
isVip = false 普通工廠
爲保證品質,本店所有藥品只接受預定:
接到普通訂單:行軍丹 切換普通工廠
開始製作:祖傳祕法祕製七天
製作完成-->行軍丹
打包藥品:行軍丹
---- 行軍丹 使用說明 ----
具有功效:江湖中常見的療傷藥丸,尺寸小,便於攜帶,服用後見效快,恢復生命100點。
接到普通訂單:金瘡藥 切換普通工廠
開始製作:祖傳祕法祕製七七四十九天
製作完成-->金瘡藥
打包藥品:金瘡藥
---- 金瘡藥 使用說明 ----
具有功效:聞名天下的佛門療傷奇藥,闖蕩江湖必備,加速癒合,服用後立即恢復生命500點。
接到普通訂單:黑玉斷續膏 切換普通工廠
開始製作:祖傳祕法祕製九九八十一天
製作完成-->黑玉斷續膏
打包藥品:黑玉斷續膏
---- 黑玉斷續膏 使用說明 ----
具有功效:傳說中的稀世祕藥,有再造之力,神奇無比,其價堪比黃金,服用後立即恢復生命2500點。
isVip = true 切換超級工廠
爲保證品質,本店所有藥品只接受預定:
接到VIP訂單:行軍丹 切換超級工廠
開始製作:祖傳祕法祕製七天
製作完成-->超級行軍丹
打包藥品:超級行軍丹
---- 超級行軍丹 使用說明 ----
具有功效:江湖中常見的療傷藥丸,尺寸小,便於攜帶,服用後見效快,恢復生命100點,具備超級功效-->同時恢復50點內力。
接到VIP訂單:金瘡藥 切換超級工廠
開始製作:祖傳祕法祕製七七四十九天
製作完成-->超級金瘡藥
打包藥品:超級金瘡藥
---- 超級金瘡藥 使用說明 ----
具有功效:聞名天下的佛門療傷奇藥,闖蕩江湖必備,加速癒合,服用後立即恢復生命500點,具備超級功效-->同時恢復250點內力。
接到VIP訂單:黑玉斷續膏 切換超級工廠
開始製作:祖傳祕法祕製九九八十一天
製作完成-->超級黑玉斷續膏
打包藥品:超級黑玉斷續膏
---- 超級黑玉斷續膏 使用說明 ----
具有功效:傳說中的稀世祕藥,有再造之力,神奇無比,其價堪比黃金,服用後立即恢復生命2500點,具備超級功效-->同時恢復1000點內力。
抽象工廠模式可以快速的切換不同的系列,實現了系列和系列之間的隔離。
如果藥房接到了普通訂單,就去普通工廠下單生產,如果接到了vip訂單就去超級工廠下單生產,這樣就能快速切換生產不同的系列產品了。
總結
簡單工廠模式:如果對象的創建邏輯都比較簡單的時候,直接用new 來創建對象就可以了,推薦使用簡單工廠模式,將多個對象的創建邏輯放到一個工廠類中。雖然也會有if邏輯判斷,如果不是太複雜,也是可以接受的,也可以通過map來消除if判斷。
工廠方法模式:如果每個對象的創建邏輯都比較複雜的時候,爲了避免設計一個過於龐大的簡單工廠類,推薦使用工廠方法模式,將創建邏輯拆分得更細,每個對象的創建邏輯獨立到各自的工廠類中。同時,創建代碼抽離到獨立的工廠類之後可以方便複用。
抽象工廠模式:如果需要隨時切換不同的系列產品,推薦使用抽象工廠模式,實現不同系列之間的隔離,快速切換工廠。
華山論劍
全真教掌門王重陽「中神通」爲免江湖仇殺不斷,提出「華山論劍」,勝者爲「天下第一高手」,並可擁有《九陰真經》。
大戰在即,天下豪傑這幾日都趕往華山,華山腳下好不熱鬧,大家都想見證天下第一高手的誕生。
近日,仙草藥房忽然來了幾波神祕人物,看似都很有來頭,師父不敢怠慢,依次請入內屋詳談。
小帥發現好幾位神祕客人的訂單中都有號稱“黑黃金”的超級黑玉斷續膏,這可稀奇了,超級黑玉斷續膏貴比黃金,產量極其稀少,不是一般的客人有資格和能力預定的,師父只供應極少數的vip客戶。
小帥偷偷看了一下客戶名單,光看名字就驚出一身冷汗,他們分別是:(東邪)黃藥師,(西毒)歐陽鋒,(南帝)段智興,(北丐)洪七公。