Vue3+TypeScript实现工厂模式:用电脑组装厂带你飞
工厂模式,听起来是不是有点像“程序员开电脑组装厂”?别慌!它其实是前端开发中一种超实用的创建型设计模式,能帮你把对象的创建过程收拾得服服帖帖,让代码优雅又灵活。今天我们用Vue3和TypeScript,结合一个“组装电脑”的幽默例子,带你从头到尾搞懂简单工厂、工厂方法和抽象工厂模式,保证通俗易懂,笑中带学!
一、工厂模式是个啥?
想象你开了一家电脑组装厂,客户点单时喊:“来台游戏电脑!”你总不能每次都从零开始选CPU、装主板吧?工厂模式就像你的电脑组装流水线:客户(代码调用者)只管下单,工厂(代码逻辑)负责生产电脑(对象),至于用啥CPU、显卡,客户完全不用操心。这不就是解耦的精髓吗?
工厂模式有三种“流水线”:简单工厂、工厂方法和抽象工厂。我们用Vue3+TypeScript实现一个前端版的“电脑组装厂”,让你边组装电脑边学设计模式!
二、工厂模式的三大形态
1. 简单工厂模式:一个柜台全搞定
定义:简单工厂就像电脑组装厂的前台小哥,客户点啥(传个参数),小哥就从车间端出对应的电脑(返回对象)。简单粗暴,但所有逻辑都挤在一个工厂类里。
前端场景:假设你用Vue3开发一个电脑选购页面,客户选择电脑类型,前端通过工厂生成对应的电脑组件或数据。
// src/models/Computer.ts
export interface Computer {
name: string;
assemble(): string;
}
// 游戏电脑
export class GamingComputer implements Computer {
name = 'Gaming Computer';
assemble() {
return `💻 组装${this.name}:高性能CPU、RTX显卡,畅玩3A大作!`;
}
}
// 办公电脑
export class OfficeComputer implements Computer {
name = 'Office Computer';
assemble() {
return `💻 组装${this.name}:稳定CPU、集成显卡,办公无压力!`;
}
}
// src/factories/SimpleComputerFactory.ts
export class SimpleComputerFactory {
static createComputer(type: string): Computer {
switch (type) {
case 'gaming':
return new GamingComputer();
case 'office':
return new OfficeComputer();
default:
throw new Error('😅 老板,这个电脑我们厂里没得卖!');
}
}
}
// src/components/ComputerOrder.vue
<script setup lang="ts">
import { ref } from 'vue';
import { SimpleComputerFactory } from '../factories/SimpleComputerFactory';
const computerType = ref('gaming');
const computerMessage = ref('');
const orderComputer = () => {
try {
const computer = SimpleComputerFactory.createComputer(computerType.value);
computerMessage.value = computer.assemble();
} catch (error) {
computerMessage.value = (error as Error).message;
}
};
</script>
<template>
<div>
<h2>简单工厂点单台</h2>
<select v-model="computerType">
<option value="gaming">游戏电脑</option>
<option value="office">办公电脑</option>
</select>
<button @click="orderComputer">下单!</button>
<p>{{ computerMessage }}</p>
</div>
</template>
幽默讲解:简单工厂就像你厂里的全能小哥,啥电脑都会组装,但忙起来容易手忙脚乱(逻辑全塞在一个类里)。如果新加个“服务器电脑”,得改工厂代码,违反了“开闭原则”(对扩展开放,对修改关闭)。但它简单好上手,适合小型电脑组装厂!
优点:
- 代码简单,适合小型项目。
- 客户端(Vue组件)只管下单,不用知道电脑咋组装的。
缺点:
- 新增电脑类型要改工厂代码,可扩展性差。
- 逻辑集中在工厂类,规模大了容易变“意大利面条代码”。
2. 工厂方法模式:每种电脑专属生产线
定义:工厂方法模式就像给每种电脑开一条专属生产线(子类),每条生产线只组装一种电脑,客户找对应的生产线下单。
前端场景:在Vue3中,假设不同电脑厂(组件)有自己的组装逻辑,工厂方法让每个厂决定生产啥电脑。
// src/models/Computer.ts
export interface Computer {
name: string;
assemble(): string;
}
export class GamingComputer implements Computer {
name = 'Gaming Computer';
assemble() {
return `💻 组装${this.name}:高频CPU、RTX显卡,游戏性能拉满!`;
}
}
export class OfficeComputer implements Computer {
name = 'Office Computer';
assemble() {
return `💻 组装${this.name}:低功耗CPU、集成显卡,办公利器!`;
}
}
// src/factories/ComputerStore.ts
export abstract class ComputerStore {
abstract createComputer(type: string): Computer;
orderComputer(type: string) {
const computer = this.createComputer(type);
return computer.assemble();
}
}
export class GamingComputerStore extends ComputerStore {
createComputer(type: string): Computer {
if (type === 'gaming') {
return new GamingComputer();
}
throw new Error('😓 游戏厂只组装游戏电脑,别点别的!');
}
}
export class OfficeComputerStore extends ComputerStore {
createComputer(type: string): Computer {
if (type === 'office') {
return new OfficeComputer();
}
throw new Error('😓 办公厂专做办公电脑,别的没有!');
}
}
// src/components/ComputerStore.vue
<script setup lang="ts">
import { ref } from 'vue';
import { GamingComputerStore, OfficeComputerStore } from '../factories/ComputerStore';
const storeType = ref('gaming');
const computerType = ref('gaming');
const computerMessage = ref('');
const orderComputer = () => {
try {
const store = storeType.value === 'gaming' ? new GamingComputerStore() : new OfficeComputerStore();
computerMessage.value = store.orderComputer(computerType.value);
} catch (error) {
computerMessage.value = (error as Error).message;
}
};
</script>
<template>
<div>
<h2>工厂方法点单台</h2>
<select v-model="storeType">
<option value="gaming">游戏电脑厂</option>
<option value="office">办公电脑厂</option>
</select>
<select v-model="computerType">
<option value="gaming">游戏电脑</option>
<option value="office">办公电脑</option>
</select>
<button @click="orderComputer">下单!</button>
<p>{{ computerMessage }}</p>
</div>
</template>
幽默讲解:工厂方法就像开了好几家连锁电脑厂,每家厂专精一种电脑,互不干扰。想加新电脑?开个新厂(新子类)就行,老厂代码不动,符合“开闭原则”。但厂多了(子类多了),代码量也上去了,适合中型电脑组装帝国!
优点:
- 符合“开闭原则”,新增电脑类型只需加新厂(子类)。
- 每种电脑的创建逻辑隔离,代码更清晰。
缺点:
- 每种电脑都要建一个工厂类,代码量增加。
- 客户端需要知道具体工厂类(电脑厂)。
3. 抽象工厂模式:一站式配件生产线
定义:抽象工厂模式像个“电脑配件超市”,不仅生产电脑,还提供整套配件(CPU、显卡、主板等),确保每种电脑的配件风格统一。
前端场景:在Vue3中,假设电脑厂需要一整套配件(UI组件、数据模型等),抽象工厂负责提供整套风格一致的“配件”。
// src/models/Components.ts
export interface CPU {
getType(): string;
}
export interface GPU {
getType(): string;
}
export class GamingCPU implements CPU {
getType() {
return '高性能游戏CPU';
}
}
export class GamingGPU implements GPU {
getType() {
return 'RTX系列显卡';
}
}
export class OfficeCPU implements CPU {
getType() {
return '低功耗办公CPU';
}
}
export class OfficeGPU implements GPU {
getType() {
return '集成显卡';
}
}
// src/factories/ComputerComponentFactory.ts
export interface ComputerComponentFactory {
createCPU(): CPU;
createGPU(): GPU;
}
export class GamingComputerComponentFactory implements ComputerComponentFactory {
createCPU(): CPU {
return new GamingCPU();
}
createGPU(): GPU {
return new GamingGPU();
}
}
export class OfficeComputerComponentFactory implements ComputerComponentFactory {
createCPU(): CPU {
return new OfficeCPU();
}
createGPU(): GPU {
return new OfficeGPU();
}
}
// src/components/ComputerMaker.vue
<script setup lang="ts">
import { ref } from 'vue';
import { GamingComputerComponentFactory, OfficeComputerComponentFactory } from '../factories/ComputerComponentFactory';
const factoryType = ref('gaming');
const computerMessage = ref('');
const makeComputer = () => {
const factory = factoryType.value === 'gaming' ? new GamingComputerComponentFactory() : new OfficeComputerComponentFactory();
const cpu = factory.createCPU();
const gpu = factory.createGPU();
computerMessage.value = `💻 电脑配件:${cpu.getType()} + ${gpu.getType()}`;
};
</script>
<template>
<div>
<h2>抽象工厂配件台</h2>
<select v-model="factoryType">
<option value="gaming">游戏配置</option>
<option value="office">办公配置</option>
</select>
<button @click="makeComputer">组装电脑!</button>
<p>{{ computerMessage }}</p>
</div>
</template>
幽默讲解:抽象工厂就像个“电脑配件批发市场”,你要游戏配置?给你整套游戏CPU+显卡!要办公配置?给你办公全套!客户下单时不用管配件细节,直接拿来组装电脑,完美统一风格!但这“批发市场”代码有点复杂,适合大型连锁电脑帝国。
优点:
- 保证一整套配件风格一致(例如UI组件风格统一)。
- 支持复杂对象家族的创建,扩展性强。
缺点:
- 代码结构复杂,类和接口数量多。
- 新增产品族需要改动较多代码。
三、应用场景
工厂模式在前端开发中超级实用,尤其在Vue3项目中:
- 动态组件加载:根据用户选择加载不同Vue组件(例如不同风格的表单)。
- 主题切换:抽象工厂可生成整套主题(按钮、输入框、卡片等),确保UI风格统一。
- 数据模型生成:根据API返回的数据类型,生成对应的TypeScript模型实例。
- 插件系统:为不同功能模块提供统一的插件创建接口,方便扩展。
幽mer例子:想象你的Vue3项目是个电脑组装厂,用户点“高性能模式”电脑(主题),工厂直接吐出一整套高性能风格组件;点“办公助手”电脑,工厂给你生成办公优化组件。客户(代码)只管用,工厂管生产!
四、适用性
- 需要动态创建对象:例如Vue组件根据用户输入动态加载。
- 需要解耦创建逻辑:隐藏组件或数据模型的创建细节,让代码更灵活。
- 支持可扩展产品:新增组件或主题时,只需加新工厂,不改现有代码。
- 统一对象家族:抽象工厂适合生成整套UI组件或数据模型,保持一致性。
五、注意事项
-
选择合适的工厂模式:
- 小项目用简单工厂,快速上手。
- 中型项目用工厂方法,扩展性更好。
- 大型项目用抽象工厂,适合复杂对象家族。
-
TypeScript的优势:
- 用接口(
interface)定义电脑和配件,确保类型安全。 - 善用TypeScript的类型推断,减少运行时错误。
- 用接口(
-
** композиция考虑**:
- 工厂模式增加了一层间接调用,注意不要过度封装。
- 对于简单组件,考虑直接实例化,省去工厂开销。
-
社区支持:
- Vue3生态(如VueUse、Pinia)中常用工厂模式思想,学习相关源码能加深理解。
- 参考TypeScript官方文档,优化类型定义。
幽默提示:别让你的工厂变成“电脑黑店”,生产一堆没人要的怪配置电脑(不必要的复杂逻辑)!保持简单,客户才爱买!
六、总结
工厂模式就像前端开发者的“电脑组装流水线”,让对象创建变得优雅又灵活。在Vue3+TypeScript项目中,简单工厂适合快速开发,工厂方法适合扩展性需求,抽象工厂适合复杂UI或数据模型的统一管理。