咖啡机进阶优化
使用设计模式优化咖啡机代码,实现装饰器和建造者模式
问题
基于基础咖啡机实现,使用设计模式进行优化改造,提升代码的扩展性和可维护性。
解答
基础版本(存在的问题)
// 基础版本 - 扩展性差,添加新配料需要修改类
class Coffee {
constructor(type) {
this.type = type;
this.price = 10;
this.ingredients = [];
}
addMilk() {
this.ingredients.push('milk');
this.price += 3;
return this;
}
addSugar() {
this.ingredients.push('sugar');
this.price += 1;
return this;
}
// 每添加一种配料就要新增方法...
}
优化一:装饰器模式
// 咖啡基类
class Beverage {
getDescription() {
return 'Unknown Beverage';
}
cost() {
return 0;
}
}
// 具体咖啡
class Espresso extends Beverage {
getDescription() {
return 'Espresso';
}
cost() {
return 15;
}
}
class Latte extends Beverage {
getDescription() {
return 'Latte';
}
cost() {
return 20;
}
}
// 装饰器基类
class CondimentDecorator extends Beverage {
constructor(beverage) {
super();
this.beverage = beverage;
}
}
// 具体装饰器 - 牛奶
class Milk extends CondimentDecorator {
getDescription() {
return `${this.beverage.getDescription()}, Milk`;
}
cost() {
return this.beverage.cost() + 3;
}
}
// 具体装饰器 - 摩卡
class Mocha extends CondimentDecorator {
getDescription() {
return `${this.beverage.getDescription()}, Mocha`;
}
cost() {
return this.beverage.cost() + 5;
}
}
// 具体装饰器 - 奶泡
class Whip extends CondimentDecorator {
getDescription() {
return `${this.beverage.getDescription()}, Whip`;
}
cost() {
return this.beverage.cost() + 2;
}
}
// 使用示例
let coffee = new Espresso();
coffee = new Milk(coffee);
coffee = new Mocha(coffee);
coffee = new Whip(coffee);
console.log(coffee.getDescription()); // Espresso, Milk, Mocha, Whip
console.log(coffee.cost()); // 25
优化二:建造者模式
// 咖啡产品
class Coffee {
constructor() {
this.type = '';
this.size = 'medium';
this.milk = false;
this.sugar = 0;
this.extras = [];
}
describe() {
const parts = [this.size, this.type];
if (this.milk) parts.push('with milk');
if (this.sugar > 0) parts.push(`${this.sugar} sugar`);
if (this.extras.length) parts.push(this.extras.join(', '));
return parts.join(' ');
}
}
// 建造者
class CoffeeBuilder {
constructor() {
this.coffee = new Coffee();
}
setType(type) {
this.coffee.type = type;
return this;
}
setSize(size) {
this.coffee.size = size;
return this;
}
addMilk() {
this.coffee.milk = true;
return this;
}
addSugar(amount = 1) {
this.coffee.sugar = amount;
return this;
}
addExtra(extra) {
this.coffee.extras.push(extra);
return this;
}
build() {
return this.coffee;
}
}
// 指挥者 - 预设配方
class Barista {
static makeAmericano(builder) {
return builder
.setType('Americano')
.setSize('large')
.build();
}
static makeCapuccino(builder) {
return builder
.setType('Capuccino')
.addMilk()
.addExtra('foam')
.build();
}
static makeMocha(builder) {
return builder
.setType('Mocha')
.addMilk()
.addExtra('chocolate')
.addExtra('whip cream')
.build();
}
}
// 使用示例
// 自定义咖啡
const customCoffee = new CoffeeBuilder()
.setType('Latte')
.setSize('small')
.addMilk()
.addSugar(2)
.addExtra('vanilla')
.build();
console.log(customCoffee.describe());
// small Latte with milk 2 sugar vanilla
// 使用预设配方
const mocha = Barista.makeMocha(new CoffeeBuilder());
console.log(mocha.describe());
// medium Mocha with milk chocolate, whip cream
优化三:结合 TypeScript 和事件系统
// 类型定义
type CoffeeSize = 'small' | 'medium' | 'large';
type CoffeeEvent = 'brewing' | 'ready' | 'error';
interface CoffeeOptions {
type: string;
size: CoffeeSize;
milk: boolean;
sugar: number;
}
// 事件发射器
class EventEmitter {
private events: Map<string, Function[]> = new Map();
on(event: string, callback: Function) {
if (!this.events.has(event)) {
this.events.set(event, []);
}
this.events.get(event)!.push(callback);
return this;
}
emit(event: string, ...args: any[]) {
const callbacks = this.events.get(event);
if (callbacks) {
callbacks.forEach(cb => cb(...args));
}
}
}
// 咖啡机
class CoffeeMachine extends EventEmitter {
private queue: CoffeeOptions[] = [];
private isBrewing = false;
// 添加订单
order(options: CoffeeOptions) {
this.queue.push(options);
this.processQueue();
return this;
}
// 处理队列
private async processQueue() {
if (this.isBrewing || this.queue.length === 0) return;
this.isBrewing = true;
const order = this.queue.shift()!;
this.emit('brewing', order);
// 模拟制作过程
await this.brew(order);
this.emit('ready', order);
this.isBrewing = false;
// 继续处理下一个
this.processQueue();
}
private brew(options: CoffeeOptions): Promise<void> {
const time = options.size === 'large' ? 3000 : 2000;
return new Promise(resolve => setTimeout(resolve, time));
}
}
// 使用示例
const machine = new CoffeeMachine();
machine
.on('brewing', (order: CoffeeOptions) => {
console.log(`正在制作: ${order.size} ${order.type}`);
})
.on('ready', (order: CoffeeOptions) => {
console.log(`完成: ${order.type}`);
});
machine
.order({ type: 'Latte', size: 'medium', milk: true, sugar: 1 })
.order({ type: 'Espresso', size: 'small', milk: false, sugar: 0 });
关键点
- 装饰器模式:动态添加功能,避免类爆炸,配料可自由组合
- 建造者模式:分步构建复杂对象,链式调用提升可读性
- 指挥者角色:封装常用配方,简化客户端代码
- 事件驱动:解耦制作过程和状态通知,支持异步操作
- TypeScript:类型约束减少运行时错误,提升代码可维护性
目录