在面向對象程式設計中,new 對象是最常見的操作,但創建對象的過程往往伴隨著初始化參數、處理構造細節等瑣事,這讓開發者不得不分心於對象創建而非核心業務邏輯,嚴重拖慢開發效率。工廠模式與抽象工廠模式的出現,正是為了解決這一痛點,讓開發者能專注於業務實現,而將對象創建的複雜性封裝起來。
Hibernate 中的 SessionFactory 即是典型應用。
開發中最常用的形式,程式碼量少、結構簡單,但擴展性差,新增產品需修改工廠類原始碼,違反開閉原則。
public class Demo {
public static void main(String[] args) {
Car car = CarFactory.createCar("dz");
car.run();
Car car2 = CarFactory.createCar("at");
car2.run();
}
}
interface Car { void run(); }
class Dz implements Car {
public void run() { System.out.println("大眾汽車在跑"); }
}
class At implements Car {
public void run() { System.out.println("奧拓汽車在跑"); }
}
class CarFactory {
public static Car createCar(String type) {
if ("dz".equals(type)) {
System.out.println("創建了一個大眾車");
return new Dz();
}
if ("at".equals(type)) {
System.out.println("創建了一個奧拓車");
return new At();
}
return null;
}
}
將創建邏輯延遲到子類,新增產品只需新增對應工廠類,無需修改既有代碼,符合開閉原則,但類數量增加,結構較複雜。
public class Demo {
public static void main(String[] args) {
AtFactory atFactory = new AtFactory();
DzFactory dzFactory = new DzFactory();
Car at = atFactory.createCar();
Car dz = dzFactory.createCar();
at.run();
dz.run();
}
}
interface Car { void run(); }
class Dz implements Car {
public void run() { System.out.println("大眾汽車在跑"); }
}
class At implements Car {
public void run() { System.out.println("奧拓汽車在跑"); }
}
interface CarFactory { Car createCar(); }
class DzFactory implements CarFactory {
public Car createCar() { return new Dz(); }
}
class AtFactory implements CarFactory {
public Car createCar() { return new At(); }
}
針對「產品族」而非單一產品。工廠方法針對不同類別產品(如奧迪、大眾),抽象工廠則對同一產品進行等級劃分(如大眾高端車、低端車)。可視為工廠方法的細化,一個針對不同產品,一個針對同一產品家族。
public class Demo {
public static void main(String[] args) {
Car carFactory = new GDCarFactory();
FDZ fdz = carFactory.createFdz();
fdz.zhuansu();
}
}
interface FDZ { void zhuansu(); }
class GDFDZ implements FDZ { public void zhuansu() { System.out.println("高端發動機轉速快"); } }
class DDFDZ implements FDZ { public void zhuansu() { System.out.println("低端發動機轉速慢"); } }
interface ZY { void shushidu(); }
class GDZY implements ZY { public void shushidu() { System.out.println("高端座椅很舒適"); } }
class DDZY implements ZY { public void shushidu() { System.out.println("低端座椅不舒適"); } }
interface LT { void mosundu(); }
class GDLT implements LT { public void mosundu() { System.out.println("高端輪胎不磨損"); } }
class DDLT implements LT { public void mosundu() { System.out.println("低端輪胎磨損快"); } }
interface Car {
FDZ createFdz();
ZY createZy();
LT createLt();
}
class GDCarFactory implements Car {
public FDZ createFdz() { return new GDFDZ(); }
public ZY createZy() { return new GDZY(); }
public LT createLt() { return new GDLT(); }
}
class DDCarFactory implements Car {
public FDZ createFdz() { return new DDFDZ(); }
public ZY createZy() { return new DDZY(); }
public LT createLt() { return new DDLT(); }
}
| 模式 | 優點 | 缺點 |
|---|---|---|
| 簡單工廠 | 設計簡單、代碼少 | 擴展性差,需修改原代碼 |
| 工廠方法 | 擴展性強,符合開閉原則 | 增加代碼複雜度 |
| 抽象工廠 | 管理產品族,保證客戶端只使用同一族產品 | 新增產品等級麻煩,需修改所有工廠類 |
掌握三種工廠模式的適用場景,能讓你在架構設計中遊刃有餘,根據業務複雜度選擇最合適的模式。