使代码难以维护、扩展或理解的结构性问题
表明代码库设计存在更深层问题的结构性问题
使代码难以修改和测试的面向对象设计问题
违反基本设计原则,导致代码僵化和脆弱
过于复杂的代码路径,难以理解、测试或安全维护
指示代码需要重构的客观标准
方法应该能在一屏内显示
类应该有单一职责
考虑使用选项对象
提取函数或使用提前返回
路径太多,无法可靠测试
提取到共享函数
了解重构顾问如何识别问题并建议具体的应用模式
function processOrder(order) {
// 验证订单
if (!order.items || order.items.length === 0) {
throw new Error('订单为空')
}
if (!order.customer) {
throw new Error('没有客户')
}
// 计算总额
let subtotal = 0
for (const item of order.items) {
subtotal += item.price * item.quantity
}
const tax = subtotal * 0.1
const total = subtotal + tax
// 应用折扣
let discount = 0
if (order.customer.isPremium) {
discount = total * 0.15
} else if (subtotal > 100) {
discount = total * 0.05
}
return total - discount
}方法做了4件事:验证、计算、税费、折扣
function processOrder(order) {
validateOrder(order)
const subtotal = calculateSubtotal(order.items)
const total = applyTax(subtotal)
return applyDiscount(total, order.customer)
}
function validateOrder(order) {
if (!order.items?.length) throw new Error('订单为空')
if (!order.customer) throw new Error('没有客户')
}
function calculateSubtotal(items) {
return items.reduce((sum, item) =>
sum + item.price * item.quantity, 0)
}提取方法:每个函数只做好一件事
function calculateShipping(order) {
switch (order.shippingType) {
case 'express':
return order.weight * 5.0 + 15
case 'standard':
return order.weight * 2.5 + 5
case 'economy':
return order.weight * 1.0
case 'freight':
return order.weight * 0.5 + 50
default:
throw new Error('未知类型')
}
}Switch 语句随着每种新配送类型而增长
interface ShippingStrategy {
calculate(weight: number): number
}
const shippingStrategies: Record<string, ShippingStrategy> = {
express: { calculate: w => w * 5.0 + 15 },
standard: { calculate: w => w * 2.5 + 5 },
economy: { calculate: w => w * 1.0 },
freight: { calculate: w => w * 0.5 + 50 },
}
function calculateShipping(order) {
const strategy = shippingStrategies[order.shippingType]
if (!strategy) throw new Error('未知类型')
return strategy.calculate(order.weight)
}策略模式:无需修改现有代码即可添加新类型
class OrderProcessor {
calculateTax(order) {
const subtotal = order.items.reduce((sum, item) =>
sum + item.price * item.quantity, 0)
const taxRate = order.customer.region === 'EU'
? order.customer.country.vatRate
: 0.0
return subtotal * taxRate
}
}OrderProcessor 对 Order 和 Customer 的内部了解过多
class Order {
calculateSubtotal() {
return this.items.reduce((sum, item) =>
sum + item.price * item.quantity, 0)
}
calculateTax() {
return this.calculateSubtotal() * this.customer.getTaxRate()
}
}
class Customer {
getTaxRate() {
return this.region === 'EU' ? this.country.vatRate : 0.0
}
}将行为移至拥有数据的类
重构顾问不仅仅测量指标——它理解设计模式并建议 能够改善代码结构的具体重构技术。
识别代码结构中的代码异味和反模式
建议具体模式:提取方法、替换条件语句、移动方法
检查是否遵循 SRP、OCP、LSP、ISP 和 DIP
测量指标
计算方法/类长度和复杂度评分
识别模式
检测代码异味和设计反模式
检查 SOLID
验证是否遵循设计原则
建议重构
推荐具体模式,如提取方法、用多态替换条件语句
专注于会导致维护问题的问题,而不是风格细节
必须在多处修改的复制粘贴代码
做太多事情、无法测试的类
路径太多、无法可靠测试的函数
优先处理结构性问题
技术债务呈指数增长。
重构顾问帮您尽早发现。