前言(一些廢話,可以忽略)
- 工廠模式是非常重要的一種設計模式,相比單例模式來說,更有結構上的設計,有思想上深一層的東西,但是和跟複雜的模式相比,其實也是很簡單的。
- 網絡上有很多工廠模式的講解,如果你看得比較多,你會發現,一會這麼實現,一會那麼實現,怎麼感覺每一篇文章講得都大同小異,又感覺不太一樣,讓人很是迷糊。
- 是的,開始的時候我也是這樣迷茫,當我繼續閱讀更多的設計模式的時候,恍然大悟。這不就是大師打拳的境界麼,神似而形異。
- 其實設計模式就是這樣的,不要說同一種設計模式都有相似的地方,哪怕是不同的設計模式,它們的結構也大同小異,我們要做的,是將設計的原則精神掌握內化,而這些設計模式,只是一個工具,幫主你內化代碼設計精神的工具,舉個例子,具體A講的工廠模式和B說的工廠模式可能不一樣,這不重要,重要的是他們所講的工廠模式的精髓是一樣的。
- 所以在你學習設計模式的時候,期望大家能夠自己進行演化,這樣更能方便大家,使大家更容易,更快速的內化掌握代碼設計精髓。
- PS.部分類實現見文末
簡單工廠模式
- 這是將類創建進行簡單封裝的模式,很容易就能夠想到,將需要的對象封裝在一個方法,通過參數判斷需要創建哪個類對象
/**
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:09
**/
public class SimpleAeratedWaterFactory {
public ColaAeratedWater getAeratedWater(String type){
if("ColaOriginal".equals(type)){
return new ColaOriginal();
}else if("ColaBule".equals(type)){
return new ColaBule();
}else if("ColaDiet".equals(type)){
return new ColaDiet();
}else{
throw new RuntimeException("沒有此類型可樂");
}
}
}
- 調用也簡單,無需解釋
/**
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:09
**/
public class SimpleFactoryMode {
public static void main(String[] args) {
SimpleAeratedWaterFactory factory = new SimpleAeratedWaterFactory();
ColaAeratedWater water = factory.getAeratedWater("ColaOriginal");
System.out.println(water.getName());
}
}
- 存在一個問題,如果要增加的新的可樂口味,我們不僅需要新增實現不同味道的可樂,而且還需要在工廠中添加if else代碼,據說這裏是違反ocp原則,是的,自己仔細想一想也是,工廠代碼被修改了
工廠方法模式
- 我們將可樂的不同味道,實現在不同的類中,讓這個類去實現一個統一的創建可樂的工廠,即所謂網絡上流傳的將具體的實現延遲到子類中進行實現
/**
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:10
**/
public interface ColaFactory {
ColaAeratedWater createCola();
}
- 藍色口味的可樂,實現可樂工廠ColaFactory實現其方法,返回藍色可樂對象
/**
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:10
**/
public class BuleColaFactory implements ColaFactory {
@Override
public ColaAeratedWater createCola() {
return new ColaBule();
}
}
同理,無糖口味可樂的工廠
/**
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:10
**/
public class DietColaFactory implements ColaFactory {
@Override
public ColaAeratedWater createCola() {
return new ColaDiet();
}
}
- 在使用的時候,通過創建對應口味的可樂工廠,調用同樣的創建可樂方法
/**
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:08
**/
public class FactoryMethodMode {
public static void main(String[] args) {
ColaFactory factory = new BuleColaFactory();
ColaAeratedWater water = factory.createCola();
System.out.println(water.getName());
}
}
- 簡單畫一下工廠方法模式的uml圖
抽象工廠模式
- 在工廠方法模式的基礎上進行擴展,比如要新增雪碧Sprite,工廠方法模式似乎就不能滿足設計模式原則的擴展需求了
- 將藍色可樂工廠進一步抽象爲藍色汽水工廠,這樣不僅可以生產藍色可樂,也可以生產藍色雪碧(當然,我們目前沒有藍色雪碧,這種情況如何處理,我是有點木訥,是實現一個空方法還是在實現的方法裏拋出異常,又或是有更好的方法,希望看到此文的同學能告訴我)或其他藍色口味汽水
/**
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:11
**/
public abstract class BuleAeratedWaterFactory implements AeratedWaterFactory {
@Override
public ColaAeratedWater createColaAeratedWater() {
return new ColaBule();
}
@Override
public SpriteAeratedWater createSpriteAeratedWater() {
return null;
}
}
- 接下來是原味的汽水,可樂和雪碧都有,都得實現
/**
*
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:11
**/
public class OriginalAeratedWaterFactory implements AeratedWaterFactory{
@Override
public ColaAeratedWater createColaAeratedWater() {
return new ColaOriginal();
}
@Override
public SpriteAeratedWater createSpriteAeratedWater() {
return new SpriteOriginal();
}
}
抽象工廠,即可以生產可樂也可以生產雪碧,在擴展的時候,直接添加其他汽水飲料
/**
* absFactory
*
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:10
**/
public interface AeratedWaterFactory {
ColaAeratedWater createColaAeratedWater();
SpriteAeratedWater createSpriteAeratedWater();
//增加其他汽水
//SodaAeratedWater createSodaAeratedWater();
}
- 使用,創建不同口味的汽水工程,然後生產需要的汽水
/**
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:10
**/
public class AbsFactoryMode {
public static void main(String[] args) {
AeratedWaterFactory originalAeratedWaterFactory = new OriginalAeratedWaterFactory();
AeratedWater water = originalAeratedWaterFactory.createColaAeratedWater();
System.out.println(water.getName());
}
}
其他類
/**
* 汽水
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:11
**/
public interface AeratedWater {
String getName();
}
/**
* 工廠方法模式
* 使用的可樂父接口(也可以不要 用AeratedWater代替 個人認爲這些就是所謂的在學習過程中或初學時__不需要特別糾結的細節__ 在使用過程中遇到情況再隨機應變)
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:09
**/
public interface ColaAeratedWater extends AeratedWater{
}
/**
* 藍色可樂
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:09
**/
public class ColaBule implements ColaAeratedWater {
@Override
public String getName() {
return "ColaBule";
}
}
/**
* 原味可樂
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:09
**/
public class ColaOriginal implements ColaAeratedWater {
@Override
public String getName() {
return "ColaOriginal";
}
}
/**
* 雪碧
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:10
**/
public interface SpriteAeratedWater extends AeratedWater{
}
/**
* 原味雪碧
* @program: ade-someproblem
* @author: cade franklin
* @create: 2019-12-21 21:11
**/
public class SpriteOriginal implements SpriteAeratedWater {
@Override
public String getName() {
return "SpriteOriginal";
}
}
總結
- 工廠模式的三種基本分支大概就是這樣了,個人感覺自己還是要理解其精神內涵,不要盲目的生搬硬套,不能鑽牛角尖,特別在當前博客氾濫相互借鑑質量不高的情況下,要有自己的理解,纔能有所提升。
願你不捨愛與自由。