设计思路
- 属性装饰器定义:使用TypeScript的属性装饰器来验证和设置订单类的属性。属性装饰器可以在类定义时对属性进行操作。
- 验证逻辑:对于每个属性,在装饰器中编写验证逻辑,确保其满足相应的条件。
- 默认值设置:当某个属性不满足条件时,根据其他属性计算并设置默认值。
代码实现
function validateOrderAmount(target: any, propertyKey: string) {
let value: number;
const getter = function () {
return value;
};
const setter = function (newValue: number) {
if (newValue <= 0) {
// 根据其他属性计算默认值,这里简单设为100
value = 100;
} else {
value = newValue;
}
};
if (delete target[propertyKey]) {
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
}
}
function validateProductQuantity(target: any, propertyKey: string) {
let value: number;
const getter = function () {
return value;
};
const setter = function (newValue: number) {
if (newValue <= 0 || !Number.isInteger(newValue)) {
// 根据其他属性计算默认值,这里简单设为1
value = 1;
} else {
value = newValue;
}
};
if (delete target[propertyKey]) {
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
}
}
function validateDiscountRate(target: any, propertyKey: string) {
let value: number;
const getter = function () {
return value;
};
const setter = function (newValue: number) {
if (newValue < 0 || newValue > 1) {
// 根据订单金额和商品数量计算默认折扣率,这里简单设为0.9
const orderAmount = target.orderAmount;
const productQuantity = target.productQuantity;
value = 0.9;
} else {
value = newValue;
}
};
if (delete target[propertyKey]) {
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
}
}
class Order {
@validateOrderAmount
orderAmount: number;
@validateProductQuantity
productQuantity: number;
@validateDiscountRate
discountRate: number;
constructor(orderAmount: number, productQuantity: number, discountRate: number) {
this.orderAmount = orderAmount;
this.productQuantity = productQuantity;
this.discountRate = discountRate;
}
}
// 测试
const order = new Order(-50, 0, 1.5);
console.log(`订单金额: ${order.orderAmount}`);
console.log(`商品数量: ${order.productQuantity}`);
console.log(`折扣率: ${order.discountRate}`);