🚀 快速安装
复制以下命令并运行,立即安装此 Skill:
npx @anthropic-ai/skills install supercent-io/skills-template/code-refactoring
💡 提示:需要 Node.js 和 NPM
代码重构
何时使用此技能
- 代码审查:发现复杂或重复的代码时
- 添加新功能之前:清理现有代码
- 修复错误之后:消除根本原因
- 解决技术债务:定期重构
指示
步骤 1:提取方法
重构前(长函数):
function processOrder(order: Order) {
// 验证
if (!order.items || order.items.length === 0) {
throw new Error('订单必须有商品');
}
if (!order.customerId) {
throw new Error('订单必须有客户');
}
// 价格计算
let total = 0;
for (const item of order.items) {
total += item.price * item.quantity;
}
const tax = total * 0.1;
const shipping = total > 100 ? 0 : 10;
const finalTotal = total + tax + shipping;
// 库存检查
for (const item of order.items) {
const product = await db.product.findUnique({ where: { id: item.productId } });
if (product.stock < item.quantity) {
throw new Error(`商品 ${product.name} 库存不足`);
}
}
// 创建订单
const newOrder = await db.order.create({
data: {
customerId: order.customerId,
items: order.items,
total: finalTotal,
status: 'pending'
}
});
return newOrder;
}
重构后(提取方法):
async function processOrder(order: Order) {
validateOrder(order);
const total = calculateTotal(order);
await checkInventory(order);
return await createOrder(order, total);
}
function validateOrder(order: Order) {
if (!order.items || order.items.length === 0) {
throw new Error('订单必须有商品');
}
if (!order.customerId) {
throw new Error('订单必须有客户');
}
}
function calculateTotal(order: Order): number {
const subtotal = order.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
const tax = subtotal * 0.1;
const shipping = subtotal > 100 ? 0 : 10;
return subtotal + tax + shipping;
}
async function checkInventory(order: Order) {
for (const item of order.items) {
const product = await db.product.findUnique({ where: { id: item.productId } });
if (product.stock < item.quantity) {
throw new Error(`商品 ${product.name} 库存不足`);
}
}
}
async function createOrder(order: Order, total: number) {
return await db.order.create({
data: {
customerId: order.customerId,
items: order.items,
total,
status: 'pending'
}
});
}
步骤 2:消除重复
重构前(重复):
async function getActiveUsers() {
return await db.user.findMany({
where: { status: 'active', deletedAt: null },
select: { id: true, name: true, email: true }
});
}
async function getActivePremiumUsers() {
return await db.user.findMany({
where: { status: 'active', deletedAt: null, plan: 'premium' },
select: { id: true, name: true, email: true }
});
}
重构后(提取公共逻辑):
type UserFilter = {
plan?: string;
};
async function getActiveUsers(filter: UserFilter = {}) {
return await db.user.findMany({
where: {
status: 'active',
deletedAt: null,
...filter
},
select: { id: true, name: true, email: true }
});
}
// 使用
const allActiveUsers = await getActiveUsers();
const premiumUsers = await getActiveUsers({ plan: 'premium' });
步骤 3:用多态替换条件判断
重构前(长 if-else):
class PaymentProcessor {
process(payment: Payment) {
if (payment.method === 'credit_card') {
// 信用卡处理
const cardToken = this.tokenizeCard(payment.card);
const charge = this.chargeCreditCard(cardToken, payment.amount);
return charge;
} else if (payment.method === 'paypal') {
// PayPal处理
const paypalOrder = this.createPayPalOrder(payment.amount);
const approval = this.getPayPalApproval(paypalOrder);
return approval;
} else if (payment.method === 'bank_transfer') {
// 银行转账处理
const transfer = this.initiateBankTransfer(payment.account, payment.amount);
return transfer;
}
}
}
重构后(多态):
interface PaymentMethod {
process(payment: Payment): Promise<PaymentResult>;
}
class CreditCardPayment implements PaymentMethod {
async process(payment: Payment): Promise<PaymentResult> {
const cardToken = await this.tokenizeCard(payment.card);
return await this.chargeCreditCard(cardToken, payment.amount);
}
}
class PayPalPayment implements PaymentMethod {
async process(payment: Payment): Promise<PaymentResult> {
const order = await this.createPayPalOrder(payment.amount);
return await this.getPayPalApproval(order);
}
}
class BankTransferPayment implements PaymentMethod {
async process(payment: Payment): Promise<PaymentResult> {
return await this.initiateBankTransfer(payment.account, payment.amount);
}
}
class PaymentProcessor {
private methods: Map<string, PaymentMethod> = new Map([
['credit_card', new CreditCardPayment()],
['paypal', new PayPalPayment()],
['bank_transfer', new BankTransferPayment()]
]);
async process(payment: Payment): Promise<PaymentResult> {
const method = this.methods.get(payment.method);
if (!method) {
throw new Error(`未知的支付方式:${payment.method}`);
}
return await method.process(payment);
}
}
步骤 4:引入参数对象
重构前(参数过多):
function createUser(
name: string,
email: string,
password: string,
age: number,
country: string,
city: string,
postalCode: string,
phoneNumber: string
) {
// ...
}
重构后(组合成对象):
interface UserProfile {
name: string;
email: string;
password: string;
age: number;
}
interface Address {
country: string;
city: string;
postalCode: string;
}
interface CreateUserParams {
profile: UserProfile;
address: Address;
phoneNumber: string;
}
function createUser(params: CreateUserParams) {
const { profile, address, phoneNumber } = params;
// ...
}
// 使用
createUser({
profile: { name: '张三', email: 'zhangsan@example.com', password: 'xxx', age: 30 },
address: { country: '中国', city: '北京', postalCode: '100000' },
phoneNumber: '+861234567890'
});
步骤 5:应用 SOLID 原则
单一职责原则:
// ❌ 反面示例:多个职责
class User {
constructor(public name: string, public email: string) {}
save() {
// 保存到数据库
}
sendEmail(subject: string, body: string) {
// 发送邮件
}
generateReport() {
// 生成报告
}
}
// ✅ 良好示例:职责分离
class User {
constructor(public name: string, public email: string) {}
}
class UserRepository {
save(user: User) {
// 保存到数据库
}
}
class EmailService {
send(to: string, subject: string, body: string) {
// 发送邮件
}
}
class UserReportGenerator {
generate(user: User) {
// 生成报告
}
}
输出格式
重构检查清单
- [ ] 函数只做一件事(单一职责原则)
- [ ] 函数名清晰描述其功能
- [ ] 函数不超过 20 行(指导原则)
- [ ] 参数不超过 3 个
- [ ] 无重复代码(DRY)
- [ ] 条件嵌套不超过 2 层
- [ ] 无魔法数字(提取为常量)
- [ ] 无需注释即可理解(自文档化)
约束条件
强制性规则(必须遵守)
- 测试先行:重构前先编写测试
- 小步快跑:一次只改一个方面
- 行为保留:无功能性变更
禁止事项(不得违反)
- 同时处理多项任务:不得同时进行重构和添加功能
- 无测试重构:存在回归风险
最佳实践
- 童子军规则:让代码比你发现时更干净
- 重构时机:红-绿-重构(测试驱动开发)
- 渐进式改进:追求一致性而非完美
- 行为保留:重构不涉及功能变更
- 小提交:按聚焦单元提交
行为验证(代码简化器集成)
步骤 A:理解当前行为
在重构前充分理解当前行为:
## 行为分析
### 输入
- [列出输入参数]
- [类型和约束]
### 输出
- [返回值]
- [副作用]
### 不变量
- [必须始终成立的条件]
- [边界情况]
### 依赖项
- [外部依赖]
- [状态依赖]
步骤 B:重构后验证
# 1. 运行测试
npm test -- --coverage
# 2. 类型检查
npx tsc --noEmit
# 3. 代码风格检查
npm run lint
# 4. 与先前行为对比(快照测试)
npm test -- --updateSnapshot
步骤 C:记录更改
## 重构总结
### 所做的更改
1. [更改 1]: [原因]
2. [更改 2]: [原因]
### 行为保留情况
- [x] 相同输入 → 相同输出
- [x] 相同副作用
- [x] 相同错误处理
### 风险与后续工作
- [潜在风险]
- [后续任务]
### 测试状态
- [ ] 单元测试:通过
- [ ] 集成测试:通过
- [ ] 端到端测试:通过
故障排除
问题:重构后测试失败
原因:发生了行为变更
解决方案:回退并隔离更改,然后重试
问题:代码仍然复杂
原因:一个函数中混合了多个职责
解决方案:提取成边界清晰的小单元
问题:性能下降
原因:引入了低效的抽象
解决方案:分析性能并优化热点路径
多智能体工作流
验证与回顾
- 第一轮(协调者):验证行为保留清单
- 第二轮(分析师):复杂度和重复性分析
- 第三轮(执行者):测试或静态分析验证
智能体角色
| 智能体 | 角色 |
|---|---|
| Claude | 重构计划、代码转换 |
| Gemini | 大规模代码库分析、模式检测 |
| Codex | 测试执行、构建验证 |
工作流示例
# 1. Gemini:代码库分析
ask-gemini "@src/ 提取高复杂度函数列表"
# 2. Claude:重构计划与执行
# 基于 IMPLEMENTATION_PLAN.md 工作
# 3. Codex:验证
codex-cli shell "npm test && npm run lint"
参考资料
元数据
版本
- 当前版本:1.0.0
- 最后更新:2025-01-01
- 兼容平台:Claude, ChatGPT, Gemini
相关技能
标签
#重构 #代码质量 #DRY #SOLID #设计模式 #整洁代码
示例
示例 1:基本用法
示例 2:高级用法
📄 原始文档
完整文档(英文):
https://skills.sh/supercent-io/skills-template/code-refactoring
💡 提示:点击上方链接查看 skills.sh 原始英文文档,方便对照翻译。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

评论(0)