一、定义
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它提供了一种在不指定具体类的情况下创建对象的方法。工厂方法模式定义了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
二、分析
1.角色分析
-
抽象工厂类(Abstract Factory):
- 定义了一个创建产品对象的操作接口,这个接口是工厂方法,返回的类型是一个抽象的产品类型。
- 工厂方法可以由子类实现,以生成一组相关或相互依赖的对象。
-
具体工厂类(Concrete Factory):
- 实现抽象工厂类中的工厂方法,生成一组具体对象。
-
抽象产品类(Abstract Product):
- 为所有类型的产品对象声明一个通用接口。
- 客户端通过使用这个通用接口来处理所有产品对象。
-
具体产品类(Concrete Product):
- 实现抽象产品接口的具体类。
- 工厂方法返回的具体产品对象,就是这些具体产品类的实例。
2.代码分析
此处代码为vue3+ts
html
<template>
<div class="page">
<div class="main">
<div ref="mainContainer"></div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
const mainContainer = ref<HTMLDivElement | null>(null);
// 抽象产品类
class AbstractDiv {
element: HTMLDivElement | null;
constructor() {
this.element = document.createElement("div");
}
getElement() {
if (this.element) return this.element;
else return document.createElement("div");
}
}
// 具体产品类 - RedDiv
class RedDiv extends AbstractDiv {
setStyle() {
if (!this.element) return;
this.element.style.backgroundColor = "red";
this.element.style.width = "100px";
this.element.style.height = "100px";
this.element.style.margin = "10px";
this.element.style.display = "inline-block";
}
}
// 具体产品类 - GreenDiv
class GreenDiv extends AbstractDiv {
setStyle() {
if (!this.element) return;
this.element.style.backgroundColor = "green";
this.element.style.width = "100px";
this.element.style.height = "100px";
this.element.style.margin = "10px";
this.element.style.display = "inline-block";
}
}
// 抽象工厂类
abstract class AbstractDivFactory {
abstract createDiv(color: string): AbstractDiv;
}
// 具体工厂类 - ColorDivFactory
class ColorDivFactory extends AbstractDivFactory {
createDiv(color: string) {
let div;
if (color === "red") {
div = new RedDiv();
} else if (color === "green") {
div = new GreenDiv();
} else {
throw new Error(`暂不支持${color}色`);
}
div.setStyle(); // 在工厂内部直接调用setStyle方法
return div;
}
}
// 创建ColorDivFactory实例
const divFactory = new ColorDivFactory();
onMounted(() => {
// 示例用法
const container = mainContainer.value;
// 创建并添加不同颜色的div到容器中
const redDivInstance = divFactory.createDiv("red");
const greenDivInstance = divFactory.createDiv("green");
container?.appendChild(redDivInstance.getElement());
container?.appendChild(greenDivInstance.getElement());
});
</script>
<style>
.page {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
</style>
图片简单描述:
三、作用与优缺点
作用
- 封装对象的创建过程:工厂模式将对象的创建过程封装在工厂类中,用户只需调用工厂类提供的方法,而无需关心对象的具体创建细节。
- 降低耦合度:通过工厂模式,客户端代码与具体产品类之间的耦合度得到降低,使得代码更易于维护和扩展。
- 提高代码复用性:工厂模式中的工厂类可以复用,当需要创建相同类型的对象时,只需调用工厂类的方法即可,无需重复编写创建代码。
- 易于扩展和维护:当需要添加新的产品类时,只需在工厂类中添加相应的创建逻辑,而无需修改客户端代码,符合开闭原则。
优点
- 降低系统的耦合度:工厂模式通过将对象的创建过程集中到一个工厂类中来降低系统的耦合度,从而使得系统更加灵活、可扩展和易于维护。
- 隐藏对象的创建细节:工厂模式将对象的创建过程封装在工厂类中,对客户端隐藏了对象的创建细节,从而使得系统更加安全、稳定和简洁。
- 提高系统的灵活性:工厂模式可以在不修改已有代码的基础上,动态地添加、替换或删除产品对象,从而提高了系统的灵活性和可扩展性。
缺点
- 增加系统复杂性:工厂模式的引入可能会增加系统的复杂性,特别是当工厂类数量较多时,管理和维护这些工厂类可能会变得相对困难。
- 可能导致过度设计:在某些情况下,过度使用工厂模式可能导致设计过于复杂,甚至可能引入不必要的抽象和层级,使得代码难以理解和维护。
- 可能引入性能开销:由于工厂模式涉及到对象的创建和分配,可能会在一定程度上增加系统的性能开销,特别是在创建大量对象时。
参考资料
设计模式(第二版) 主编:刘伟 清华大学出版社