MST
星途 面试题库

面试题:TypeScript装饰器在复杂业务逻辑下的面向切面编程应用

假设我们有一个电商系统,其中有订单处理模块,包含创建订单、支付订单、取消订单等多个方法。现在需要使用TypeScript装饰器实现面向切面编程,在订单创建成功后进行库存扣减,支付成功后更新用户积分,取消订单时恢复库存。请设计并实现相应的装饰器及业务逻辑,阐述设计思路和代码实现细节。
13.4万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 装饰器概念:装饰器是一种特殊类型的声明,它能够附加到类声明、方法、属性或参数上,为这些目标添加额外的行为或元数据。
  2. 订单创建:在创建订单成功后触发库存扣减,所以创建一个装饰器 @afterCreateOrder 来处理库存扣减逻辑。
  3. 支付订单:支付成功后更新用户积分,创建装饰器 @afterPayOrder 来处理积分更新逻辑。
  4. 取消订单:取消订单时恢复库存,创建装饰器 @beforeCancelOrder 来处理库存恢复逻辑。

代码实现细节

// 库存管理类
class Inventory {
    private stock: number;
    constructor(initialStock: number) {
        this.stock = initialStock;
    }
    decreaseStock(amount: number) {
        if (this.stock >= amount) {
            this.stock -= amount;
            console.log(`库存减少 ${amount},剩余库存 ${this.stock}`);
        } else {
            console.log('库存不足');
        }
    }
    increaseStock(amount: number) {
        this.stock += amount;
        console.log(`库存增加 ${amount},当前库存 ${this.stock}`);
    }
}

// 用户积分管理类
class UserPoints {
    private points: number;
    constructor(initialPoints: number) {
        this.points = initialPoints;
    }
    updatePoints(amount: number) {
        this.points += amount;
        console.log(`用户积分更新为 ${this.points}`);
    }
}

// 订单处理类
class OrderProcessor {
    private inventory: Inventory;
    private userPoints: UserPoints;
    constructor(inventory: Inventory, userPoints: UserPoints) {
        this.inventory = inventory;
        this.userPoints = userPoints;
    }

    @afterCreateOrder
    createOrder(productAmount: number) {
        console.log('订单创建成功');
    }

    @afterPayOrder
    payOrder(pointsToAdd: number) {
        console.log('支付成功');
    }

    @beforeCancelOrder
    cancelOrder(productAmount: number) {
        console.log('订单取消成功');
    }
}

// 创建订单后库存扣减装饰器
function afterCreateOrder(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function(...args: any[]) {
        const result = originalMethod.apply(this, args);
        const productAmount = args[0];
        this.inventory.decreaseStock(productAmount);
        return result;
    };
    return descriptor;
}

// 支付订单后更新用户积分装饰器
function afterPayOrder(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function(...args: any[]) {
        const result = originalMethod.apply(this, args);
        const pointsToAdd = args[0];
        this.userPoints.updatePoints(pointsToAdd);
        return result;
    };
    return descriptor;
}

// 取消订单前恢复库存装饰器
function beforeCancelOrder(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function(...args: any[]) {
        const productAmount = args[0];
        this.inventory.increaseStock(productAmount);
        const result = originalMethod.apply(this, args);
        return result;
    };
    return descriptor;
}

// 使用示例
const inventory = new Inventory(100);
const userPoints = new UserPoints(500);
const orderProcessor = new OrderProcessor(inventory, userPoints);
orderProcessor.createOrder(10);
orderProcessor.payOrder(100);
orderProcessor.cancelOrder(10);

上述代码中:

  1. 定义了 Inventory 类来管理库存,UserPoints 类来管理用户积分。
  2. OrderProcessor 类包含订单处理的各个方法,并使用装饰器来实现面向切面编程。
  3. 分别定义了 afterCreateOrderafterPayOrderbeforeCancelOrder 装饰器,在对应的订单处理方法执行前后插入额外的业务逻辑。