什么是抽象工厂模式?JavaScript 实现一个抽象工厂模式的示例
·
什么是抽象工厂模式?
抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供一个接口用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。
与工厂方法模式(单个产品对应单个工厂)不同,抽象工厂模式聚焦于产品族(一组相关联的产品,如 “中式家具” 包含椅子、桌子、沙发,“西式家具” 也包含对应产品)的创建,通过抽象工厂接口定义产品族的创建方法,由具体工厂实现不同产品族的创建逻辑。
抽象工厂模式的核心角色
- 抽象工厂(Abstract Factory):声明创建产品族中各类产品的抽象方法(如创建椅子、桌子)。
- 具体工厂(Concrete Factory):实现抽象工厂的方法,创建某一产品族的具体产品(如 “中式工厂” 创建中式椅子、中式桌子)。
- 抽象产品(Abstract Product):定义产品族中某类产品的公共接口(如 “椅子”“桌子” 各自的抽象接口)。
- 具体产品(Concrete Product):实现抽象产品接口,是具体工厂创建的目标(如 “中式椅子”“西式桌子”)。
JavaScript 实现抽象工厂模式示例:家具工厂
以下以 “家具生产” 为例,实现抽象工厂模式。场景是:存在 “现代风格” 和 “复古风格” 两个产品族,每个产品族包含椅子、桌子两种产品。客户端通过具体工厂(现代工厂 / 复古工厂)获取对应风格的一整套家具,无需关心具体产品的创建细节。
代码实现 - javascript
// -------------- 1. 抽象产品:家具的抽象接口 --------------
// 抽象椅子
class Chair {
sitOn() {
throw new Error("子类必须实现 sitOn 方法");
}
}
// 抽象桌子
class Table {
putThings() {
throw new Error("子类必须实现 putThings 方法");
}
}
// -------------- 2. 具体产品:现代风格家具 --------------
// 现代椅子
class ModernChair extends Chair {
sitOn() {
console.log("坐在现代风格椅子上(简约设计,舒适靠背)");
}
}
// 现代桌子
class ModernTable extends Table {
putThings() {
console.log("在现代风格桌子上放东西(钢化玻璃桌面,金属支架)");
}
}
// -------------- 3. 具体产品:复古风格家具 --------------
// 复古椅子
class VintageChair extends Chair {
sitOn() {
console.log("坐在复古风格椅子上(实木雕花,皮质坐垫)");
}
}
// 复古桌子
class VintageTable extends Table {
putThings() {
console.log("在复古风格桌子上放东西(红木材质,圆形桌面)");
}
}
// -------------- 4. 抽象工厂:家具工厂接口 --------------
class FurnitureFactory {
// 创建椅子(抽象方法)
createChair() {
throw new Error("子类必须实现 createChair 方法");
}
// 创建桌子(抽象方法)
createTable() {
throw new Error("子类必须实现 createTable 方法");
}
}
// -------------- 5. 具体工厂:现代风格工厂 --------------
class ModernFurnitureFactory extends FurnitureFactory {
createChair() {
return new ModernChair(); // 生产现代椅子
}
createTable() {
return new ModernTable(); // 生产现代桌子
}
}
// -------------- 6. 具体工厂:复古风格工厂 --------------
class VintageFurnitureFactory extends FurnitureFactory {
createChair() {
return new VintageChair(); // 生产复古椅子
}
createTable() {
return new VintageTable(); // 生产复古桌子
}
}
// -------------- 7. 客户端使用 --------------
// 客户端函数:根据工厂获取一整套家具并使用
function decorateRoom(factory) {
const chair = factory.createChair();
const table = factory.createTable();
console.log("=== 布置房间 ===");
chair.sitOn();
table.putThings();
}
// 使用现代风格家具
const modernFactory = new ModernFurnitureFactory();
decorateRoom(modernFactory);
// 输出:
// === 布置房间 ===
// 坐在现代风格椅子上(简约设计,舒适靠背)
// 在现代风格桌子上放东西(钢化玻璃桌面,金属支架)
// 使用复古风格家具
const vintageFactory = new VintageFurnitureFactory();
decorateRoom(vintageFactory);
// 输出:
// === 布置房间 ===
// 坐在复古风格椅子上(实木雕花,皮质坐垫)
// 在复古风格桌子上放东西(红木材质,圆形桌面)
代码说明
- 抽象产品(Chair、Table):定义了 “椅子” 和 “桌子” 的通用接口(
sitOn、putThings),确保同一类产品具有一致的行为。 - 具体产品(ModernChair、VintageTable 等):实现了抽象产品接口,是不同风格的具体家具,属于产品族的组成部分。
- 抽象工厂(FurnitureFactory):声明了创建产品族的抽象方法(
createChair、createTable),规定具体工厂必须能生产一整套相关产品。 - 具体工厂(ModernFurnitureFactory 等):每个工厂对应一个产品族(现代 / 复古),实现抽象工厂的方法,返回该风格的具体产品。
- 客户端:通过具体工厂获取产品,无需知道产品的具体类型,只需调用产品的通用接口,实现了 “风格切换” 与 “产品使用” 的解耦。
抽象工厂模式的优势
- 产品族一致性:确保同一产品族的产品(如现代椅子和现代桌子)能相互匹配,避免风格冲突。
- 隔离具体类:客户端只依赖抽象工厂和抽象产品,无需关心具体产品的类名,降低耦合。
- 便于切换产品族:更换具体工厂即可切换整套产品(如从现代风格换成复古风格),符合 “开闭原则”。
适用场景
- 系统需要依赖多个产品族,且产品族可能频繁切换(如主题切换:浅色主题 / 深色主题的按钮、输入框等组件)。
- 产品之间存在关联或约束(如数据库访问:MySQL 的 Connection 和 Statement 需配套使用,不能与 Oracle 的组件混合)。
与工厂方法模式的区别
| 维度 | 工厂方法模式 | 抽象工厂模式 |
|---|---|---|
| 关注对象 | 单个产品的创建 | 产品族(一组相关产品)的创建 |
| 工厂职责 | 每个工厂创建一种产品 | 每个工厂创建一族产品 |
| 扩展方式 | 新增产品需新增工厂 | 新增产品族需新增工厂,新增产品需修改所有工厂(缺点) |
抽象工厂模式更适合处理 “产品族” 场景,但灵活性略低于工厂方法模式(新增单一产品时需修改所有工厂)。实际开发中需根据产品间的关联程度选择。
更多推荐



所有评论(0)