詳解設計模式 - 工廠模式(3種)
阿新 • • 發佈:2018-11-11
這篇文章作為個人學習備忘筆記,通過生活中的牛奶工廠例項,比對3種工廠模式的不同。
工廠模式一句話總結:
只對生產結果負責,不要三無產品。
生活中的工廠例子
- 小作坊:五花八門什麼都能生產,但生產質量和產品種類不一定滿足消費者的需求。
- 專業工廠:遵循一定標準,不生產其他產品,只專注於自己的產品,不斷精益求精。
- 大型國際工廠:專業、高效,無論是產品質量還是產品種類,都能讓使用者放心。
以上這三種工廠,對應到設計模式中分別就是:簡單工廠模式、工廠方法模式、抽象工廠模式。
牛奶工廠案例
有三種牛奶:蒙牛、伊利、特侖蘇,現在分不同的工廠去生產。
牛奶(它是一個抽象的東西)
/**
* 牛奶
*
* @author Zebe
*/
public interface Milk {
/**
* 牛奶名稱
* @return 返回牛奶名稱
*/
String getName();
}
蒙牛
/**
* 蒙牛牛奶
*
* @author Zebe
*/
public class MengNiu implements Milk {
@Override
public String getName() {
return "蒙牛";
}
}
伊利
/**
* 伊利牛奶
*
* @author Zebe
*/
public class YiLi implements Milk {
@Override
public String getName() {
return "伊利";
}
}
特侖蘇
/**
* 特侖蘇牛奶
*
* @author Zebe
*/
public class TeLunSu implements Milk {
@Override
public String getName() {
return "特侖蘇";
}
}
簡單工廠模式的做法
使用者要什麼就給什麼,如果自己沒有的,就給不了。
/**
* 簡單工廠(很少使用)
*
* 說明:這是簡單工廠模式(根據使用者要求來,不一定完全滿足使用者的需要)
*
* @author Zebe
*/
public class SimpleFactory {
/**
* 生產牛奶
* @param name 牛奶名稱
* @return 根據牛奶名稱返回具體的牛奶
*/
Milk getMilk(String name) {
if ("蒙牛".equals(name)) {
return new MengNiu();
} else if ("伊利".equals(name)) {
return new YiLi();
} else if ("特侖蘇".equals(name)) {
return new TeLunSu();
} else {
// 如果要新增加一種牛奶,必須修改這裡的程式碼實現
System.out.println("無法生成指定的牛奶:" + name);
return null;
}
}
}
使用測試
/**
* 簡單工廠使用測試
*
* @author Zebe
*/
public class SimpleFactoryTest {
/**
* 程式入口
* @param args 執行引數
*/
public static void main(String[] args) {
SimpleFactory factory = new SimpleFactory();
// 這裡如果名稱傳錯,會得不到想要的牛奶
System.out.println(factory.getMilk("蒙牛"));
}
}
工廠方法模式的做法
指定一個協議(標準),所有牛奶工廠都要遵循這個協議來生產。
/**
* 牛奶工廠(更加專業,不同的工廠只生產指定的牛奶)
*
* 說明:這是工廠方法模式(相當於制定一個加工協議或者標準,其他的牛奶工廠都要按照這個協議去實現)
*
* @author Zebe
*/
public interface SpecificMilkFactory {
/**
* 生產牛奶(這是一個協議)
* @return 返回牛奶
*/
Milk getMilk();
}
蒙牛工廠(按協議來生產)
/**
* 蒙牛工廠(只專注於生產蒙牛牛奶)
*
* @author Zebe
*/
public class MengNiuFactory implements SpecificMilkFactory {
@Override
public Milk getMilk() {
return new MengNiu();
}
}
伊利工廠(按協議來生產)
/**
* 伊利工廠(只專注於生產伊利牛奶)
*
* @author Zebe
*/
public class YiLiFactory implements SpecificMilkFactory {
@Override
public Milk getMilk() {
return new YiLi();
}
}
特侖蘇工廠(按協議來生產)
/**
* 特侖蘇工廠(只專注於生產特侖蘇牛奶)
*
* @author Zebe
*/
public class TeLunSuFactory implements SpecificMilkFactory {
@Override
public Milk getMilk() {
return new TeLunSu();
}
}
使用測試
/**
* 牛奶工廠測試
*
* @author Zebe
*/
public class SpecificMilkFactoryTest {
/**
* 執行入口
*
* @param args 執行引數
*/
public static void main(String[] args) {
// 要什麼牛奶,就需要指定具體某個專業的牛奶工廠
SpecificMilkFactory factory = new MengNiuFactory();
System.out.println(factory.getMilk());
}
}
抽象工廠模式的做法
更專業、質量更高,對於生產的產品有明確規範,除了能自己生產,還可以委派給其他專業的牛奶工廠生產(國內或者國外都行)。
/**
* 牛奶工廠(高階流水線工廠)
* 說明:這是抽象工廠模式(把所有能生產的牛奶抽象出來)
*
* @author Zebe
*/
public abstract class AbstractMilkFactory {
/**
* 生產蒙牛牛奶
* @return 返回蒙牛牛奶
*/
abstract Milk getMengNiu();
/**
* 生產伊利牛奶
* @return 返回伊利牛奶
*/
abstract Milk getYiLi();
/**
* 生產特侖蘇牛奶
* @return 返回特侖蘇牛奶
*/
abstract Milk getTeLunSu();
}
具體的某某牛奶工廠
/**
* 某某牛奶工廠(可以生產所有牛奶)
*
* @author Zebe
*/
public class XXXMilkFactory extends AbstractMilkFactory {
@Override
Milk getMengNiu() {
// 自己生產
return new MengNiu();
// 或委派給專業的蒙牛工廠生產(混用設計模式)
// return new MengNiuFactory().getMilk();
}
@Override
Milk getYiLi() {
// 自己生產
return new YiLi();
// 或委派給專業的伊利工廠生產(混用設計模式)
// return new YiLiFactory().getMilk();
}
@Override
Milk getTeLunSu() {
// 自己生產
return new TeLunSu();
// 或委派給專業的特侖蘇工廠生產(混用設計模式)
// return new TeLunSuFactory().getMilk();
}
}
使用測試
/**
* 牛奶工廠測試
*
* @author Zebe
*/
public class AbstractMilkFactoryTest {
/**
* 執行入口
*
* @param args 執行引數
*/
public static void main(String[] args) {
XXXMilkFactory factory = new XXXMilkFactory();
// 使用者想要什麼牛奶,應有盡有
System.out.println(factory.getMengNiu());
System.out.println(factory.getYiLi());
System.out.println(factory.getTeLunSu());
// 假設這個牛奶工廠出新產品了,例如:莫斯利安
// 那麼使用者只需要拿錢購買即可(客戶端不做改變),如下:
// System.out.println(factory.getMoSiLiAn());
}
}
小結
1、小作坊(簡單工廠模式)明顯不可靠,所以很少使用或者不使用。
2、工廠方法模式可以看成就是一個協議(介面),對應所有的具體工廠都要遵循這個協議來進行生產。
3、抽象工廠模式是最可靠的工廠模式,它最大程度地遮蔽了生產細節。