設計模式學習(三):工廠模式
設計模式學習(三):工廠模式
作者:Grey
原文地址:
工廠模式
工廠模式是創建型模式,工廠模式分為:簡單工廠,工廠方法和抽象工廠三種類型。
簡單工廠
這個模式很簡單,比如我們需要製造不同類型的滑鼠,我們只需要創建一個滑鼠工廠
public class MouseFactory {
public static Mouse createMouse(int type) {
switch (type) {
case 1:
return new HpMouse();
case 2:
return new LenovoMouse();
case 0:
default:
return new DellMouse();
}
}
public static void main(String[] args) {
Mouse mouse = MouseFactory.createMouse(1);
mouse.sayHi();
}
}
根據不同的 type 來創建不同的滑鼠即可。這個模式的缺點很明顯,違反了開閉原則 ,所以我們引入工廠方法
工廠方法
工廠方法中,我們可以定義對應產品的對應工廠,以上面這個滑鼠的例子為例,我們可以增加工廠的介面
public interface MouseFactory {
Mouse createMouse();
}
不同類型的滑鼠工廠實現這個工廠即可,以 Dell 滑鼠工廠為例
public class DellMouseFactory implements MouseFactory {
@Override
public Mouse createMouse() {
return new DellMouse();
}
}
主函數在調用的時候,直接指定工廠即可製造對應的產品了:
public class FactoryMethodDemo {
public static void main(String[] args) {
MouseFactory mf = new HpMouseFactory();
Mouse mouse = mf.createMouse();
mouse.sayHi();
}
}
工廠方法的優點是符合開閉原則,但是缺點也很明顯,就是在增加子類的時候,同時要增加一個子類的工廠,而且,只支援同一類產品的創建,不適用於同一產品族。
抽象工廠
舉例,現在需要通過工廠來製造交通工具,如果是現代的工廠,製造的就是汽車,如果是古代的工廠,製造的就是馬車, 我們可以先把工廠抽象出來,
public abstract class AbstractFactory {
protected abstract Transportation createTransportation();
protected abstract WritingInstrument createWritingInstrument();
}
交通工具也可以抽象出來
public abstract class Transportation {
protected abstract void go();
}
對於馬車和汽車來說,只需要繼承這個 Transportation 類,實現對應的 go 方法即可,以汽車為例
public class Car extends Transportation {
@Override
protected void go() {
System.out.println("car go");
}
}
對於現代工廠還是古代工廠,只需要繼承 AbstractFactory 這個抽象類,實現 createTransportation 方法即可,以現代工廠為例
public class ModernFactory extends AbstractFactory {
@Override
protected Transportation createTransportation() {
return new Car();
}
@Override
protected WritingInstrument createWritingInstrument() {
return new Pen();
}
}
主方法在調用的時候,只需要
public class Main {
public static void main(String[] args) {
AbstractFactory factory = new ModernFactory();
factory.createTransportation().go();
}
}
抽象工廠的UML圖如下:
Java SE 8 提供了 Supplier 這個函數式介面,我們可以通過這個介面很方便的實現工廠類。更多 Java SE 8 新特性見:Java SE 8 新增特性
舉例:
我們可以定義一個 MovableFactory ,裡面的 create 方法,傳入的是一個 Supplier 對象,你可以把所有 Movable 的子類實現傳給這個參數,示例如下:
public class MovableFactory {
public static Movable create(Supplier<? extends Movable> supplier) {
return supplier.get();
}
public static void main(String[] args) {
MovableFactory.create(Car::new).go();
MovableFactory.create(() -> new Ship()).go();
}
}
工廠模式應用舉例
-
JDK 中的 Calendar 類的 getInstance() 方法;
-
LogBack 中
LoggerFactory.getLogger()
方法; -
在 Spring 中,所有工廠都是 BeanFactory 的子類。通過對 BeanFactory 的實現,我們可以從 Spring 的容器訪問 Bean 。根據不同的策略調用 getBean() 方法,從而獲得具體對象。
-
Hibernate 換資料庫只需換方言和驅動就可以切換不同資料庫,也是利用了工廠模式。