Loading...
Loading...
Compare original and translation side by side
lightweight-implementation-analysis-protocollightweight-implementation-analysis-protocol❌ AVOID: getUserData(), UtilityClass, helperMethod(), DataProcessor
✅ PREFER: getUserProfile(), OrderCalculator, calculateTotal(), InvoiceGeneratorutils/helpers/common/data/doSomething()handleData()process()dataresulttempvalue🟡 Generic naming at src/utils/DataHelper.ts
- Class name "DataHelper" is too generic
- Consider: OrderValidator, CustomerRepository (based on actual responsibility)❌ 避免使用:getUserData(), UtilityClass, helperMethod(), DataProcessor
✅ 推荐使用:getUserProfile(), OrderCalculator, calculateTotal(), InvoiceGeneratorutils/helpers/common/data/doSomething()handleData()process()dataresulttempvalue🟡 通用命名问题:src/utils/DataHelper.ts
- 类名"DataHelper"过于通用
- 建议:根据实际职责改为OrderValidator、CustomerRepository等🔴 Indentation violation at User.ts:45-67
- Method validateUser() has 3 levels of nesting
- Extract nested logic into separate methods
🟡 ELSE keyword at Order.ts:23
- Can restructure with early return🔴 缩进违规:User.ts:45-67
- 方法validateUser()存在3层嵌套
- 建议:将嵌套逻辑提取为独立方法
🟡 ELSE关键字使用:Order.ts:23
- 建议:通过提前返回重构代码❌ Feature Envy:
class UserProfile {
displaySubscriptionInfo(): string {
// Accessing multiple properties of Subscription - too much interest in its data
return `Plan: ${this.subscription.planName}, ` +
`Price: $${this.subscription.monthlyPrice}/mo, ` +
`Screens: ${this.subscription.maxScreens}, ` +
`Quality: ${this.subscription.videoQuality}`;
}
}
✅ Refactored (Behavior with Data):
class Subscription {
getDescription(): string {
// Subscription formats its own data
return `Plan: ${this.planName}, ` +
`Price: $${this.monthlyPrice}/mo, ` +
`Screens: ${this.maxScreens}, ` +
`Quality: ${this.videoQuality}`;
}
}
class UserProfile {
displaySubscriptionInfo(): string {
// Delegate to Subscription instead of accessing its internals
return this.subscription.getDescription();
}
}🔴 Feature envy at OrderService.ts:34-42
- Method accesses 5 properties of Customer object
- Consider: Move logic to Customer class or extract to CustomerFormatter❌ 特性羡慕示例:
class UserProfile {
displaySubscriptionInfo(): string {
// 过度访问Subscription的多个属性,对其数据过度关注
return `Plan: ${this.subscription.planName}, ` +
`Price: $${this.subscription.monthlyPrice}/mo, ` +
`Screens: ${this.subscription.maxScreens}, ` +
`Quality: ${this.subscription.videoQuality}`;
}
}
✅ 重构后(行为与数据绑定):
class Subscription {
getDescription(): string {
// Subscription自行格式化自身数据
return `Plan: ${this.planName}, ` +
`Price: $${this.monthlyPrice}/mo, ` +
`Screens: ${this.maxScreens}, ` +
`Quality: ${this.videoQuality}`;
}
}
class UserProfile {
displaySubscriptionInfo(): string {
// 委托给Subscription,而非直接访问其内部细节
return this.subscription.getDescription();
}
}🔴 特性羡慕问题:OrderService.ts:34-42
- 方法访问Customer对象的5个属性
- 建议:将逻辑移至Customer类,或提取为CustomerFormatterconstreadonly❌ AVOID:
let total = 0;
items.forEach(item => total += item.price);
✅ PREFER:
const total = items.reduce((sum, item) => sum + item.price, 0);letconstreadonlypush()pop()splice()sort()🟡 Mutable state at Cart.ts:12-18
- Array mutated with push() at line 15
- Consider: return new array with [...items, newItem]constreadonly❌ 避免使用:
let total = 0;
items.forEach(item => total += item.price);
✅ 推荐使用:
const total = items.reduce((sum, item) => sum + item.price, 0);letconstreadonlypush()pop()splice()sort()🟡 可变状态问题:Cart.ts:12-18
- 第15行使用push()修改数组
- 建议:返回新数组,如[...items, newItem]❌ Poor encapsulation / Anemic domain:
class PlaceOrderUseCase {
placeOrder(orderId) {
const order = repository.load(orderId)
if (order.getStatus() === 'DRAFT'){
order.place()
}
repository.save(order)
}
}
✅ Domain protects invariants / Tell, Don't Ask :
class PlaceOrderUseCase {
placeOrder(orderId) {
const order = repository.load(orderId)
order.place()
repository.save(order)
}
}
class Order {
...
place() {
if (this.status !== 'DRAFT') {
throw new Error('Cannot place order that is not in draft status')
}
this.status === 'PLACED'
}
}🔴 Anemic domain model at Order.ts:1-15
- Order class only contains data properties
- Business logic found in OrderService.ts:45-89
- Consider: Move calculateTotal(), validateItems() into Order class❌ 封装性差 / 贫血领域模型示例:
class PlaceOrderUseCase {
placeOrder(orderId) {
const order = repository.load(orderId)
if (order.getStatus() === 'DRAFT'){
order.place()
}
repository.save(order)
}
}
✅ 领域保护不变量 / 告诉,不要询问 示例:
class PlaceOrderUseCase {
placeOrder(orderId) {
const order = repository.load(orderId)
order.place()
repository.save(order)
}
}
class Order {
...
place() {
if (this.status !== 'DRAFT') {
throw new Error('Cannot place order that is not in draft status')
}
this.status === 'PLACED'
}
}🔴 贫血领域模型问题:Order.ts:1-15
- Order类仅包含数据属性
- 业务逻辑位于OrderService.ts:45-89
- 建议:将calculateTotal()、validateItems()移至Order类anyas❌ AVOID:
status: string; // Can be any string
✅ PREFER:
type OrderStatus = 'pending' | 'confirmed' | 'shipped' | 'delivered';
status: OrderStatus;anyasstringnumber🔴 Type safety violation at Payment.ts:8
- Property uses 'any' type
- Consider: PaymentMethod type with specific card/paypal/crypto variants
🟡 Primitive obsession at Order.ts:12
- 'status' is string, should be union type
- Consider: type OrderStatus = 'pending' | 'confirmed' | 'shipped'anyas❌ 避免使用:
status: string; // 可以是任意字符串
✅ 推荐使用:
type OrderStatus = 'pending' | 'confirmed' | 'shipped' | 'delivered';
status: OrderStatus;anyasstringnumber🔴 类型安全违规:Payment.ts:8
- 属性使用'any'类型
- 建议:定义PaymentMethod类型,包含card/paypal/crypto等具体变体
🟡 原始类型滥用:Order.ts:12
- 'status'为string类型,应改为联合类型
- 建议:定义type OrderStatus = 'pending' | 'confirmed' | 'shipped'❌ AVOID:
function calculatePrice(item, discount, tax, shipping, insurance, gift) {
// 8 parameters handling every possible scenario
}
✅ PREFER:
function calculatePrice(item, options) {
// Simple, extensible
}🟡 Code duplication at Cart.ts:23-28 and Cart.ts:45-50
- Same validation logic duplicated
- Extract to: validateItem() method❌ 避免使用:
function calculatePrice(item, discount, tax, shipping, insurance, gift) {
// 处理所有可能场景的8个参数
}
✅ 推荐使用:
function calculatePrice(item, options) {
// 简洁且可扩展
}🟡 代码重复问题:Cart.ts:23-28和Cart.ts:45-50
- 相同的验证逻辑重复出现
- 建议:提取为validateItem()方法❌ AVOID:
items.forEach(item => {
const category = categories.find(c => c.id === item.categoryId); // O(n²)
});
✅ PREFER:
const categoryMap = new Map(categories.map(c => [c.id, c])); // O(n)
items.forEach(item => {
const category = categoryMap.get(item.categoryId); // O(1)
});find()filter()🔴 Performance issue at ProductList.ts:45-52
- Nested find() creates O(n²) complexity
- For 1000 items, this is 1M operations
- Use Map for O(n) solution❌ 避免使用:
items.forEach(item => {
const category = categories.find(c => c.id === item.categoryId); // O(n²)复杂度
});
✅ 推荐使用:
const categoryMap = new Map(categories.map(c => [c.id, c])); // O(n)复杂度
items.forEach(item => {
const category = categoryMap.get(item.categoryId); // O(1)复杂度
});find()filter()🔴 性能问题:ProductList.ts:45-52
- 嵌套的find()操作导致O(n²)复杂度
- 对于1000个条目,会产生100万次操作
- 建议:使用Map实现O(n)复杂度的解决方案undefinedundefined// 当前(存在问题)
[实际代码]
// 建议改进
[优化后的代码]
---
---lightweight-implementation-analysis-protocollightweight-implementation-analysis-protocolUnderstanding UserService.ts...
- UserService.createUser() [line 23]
↓ validates user data
↓ calls database.insert() [line 45]
↓ sends email via emailService.send() [line 52]undefined正在理解UserService.ts...
- UserService.createUser() [第23行]
↓ 验证用户数据
↓ 调用database.insert() [第45行]
↓ 通过emailService.send()发送邮件 [第52行]undefined// 当前(特性羡慕)
if (user.email && user.verified && user.role === 'admin' && user.createdAt < threshold) {
// 使用User内部属性的复杂逻辑
}
// 建议改进(告诉,不要询问)
if (user.isEligibleForAdminPromotion(threshold)) {
// User类封装逻辑
}// 当前(贫血模型)
class User {
public email: string;
public role: string;
}
// 在UserService中:
if (user.email && isValidEmail(user.email)) { ... }
// 建议改进(富领域模型)
class User {
private email: Email; // 值对象
validateEmail(): void {
// 不变量验证
}
}
---
---