代码重构艺术

代码重构艺术 4.7k人浏览 12人参与

目录

代码重构艺术:烂代码改造与设计模式实例

阶段一:展示“烂代码” (The Smelly Code)

阶段二:重构策略——引入设计模式

1. 定义策略接口 (Strategy Interface)

2. 实现具体策略 (Concrete Strategies)

3. 重构上下文 (Context)

阶段三:重构效果对比与总结

重构的价值


代码重构是软件工程中的“清洁卫生”工作,它旨在不改变代码外部行为的前提下,提升其内部结构、可读性、可维护性和可扩展性。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

本篇将通过一个“烂代码”实例,展示如何通过设计模式进行重构,突出改造前后的巨大差异。

代码重构艺术:烂代码改造与设计模式实例

我们将以一个简单的订单处理系统为例。

阶段一:展示“烂代码” (The Smelly Code)

假设我们有一个处理不同类型订单(标准订单、VIP 订单、促销订单)的类。

烂代码示例:使用大量的 if-elif-else 结构

class OrderProcessorBad:
    def __init__(self, order_data):
        self.data = order_data
        self.order_type = order_data.get('type')
        self.amount = order_data.get('amount', 0)

    def process_order(self):
        print(f"--- Processing Order {self.data['id']} ---")
        
        # 1. 基础验证
        if self.amount <= 0:
            print("Error: Amount cannot be zero.")
            return False
        
        # 2. 类型特定的处理逻辑 (最臭的 Smell)
        if self.order_type == "Standard":
            discount = 0
            shipping_fee = 10.00
            print(f"Standard Order: Calculating tax at 10%.")
            final_amount = self.amount * 1.10 + shipping_fee
            
        elif self.order_type == "VIP":
            discount = self.amount * 0.15  # VIP 15% 优惠
            shipping_fee = 0.00
            print(f"VIP Order: Applying {discount:.2f} discount.")
            final_amount = self.amount - discount
            
        elif self.order_type == "Promotion":
            if self.amount > 100:
                discount = 20.00
                print(f"Promotion Order: Applying fixed $20 discount.")
                final_amount = self.amount - discount
            else:
                print("Promotion Order: Amount too low for discount.")
                final_amount = self.amount
                shipping_fee = 5.00
        
        else:
            print(f"Error: Unknown order type {self.order_type}")
            return False

        # 3. 最终记录
        self.data['final_price'] = final_amount
        print(f"Order finalized. Total: ${final_amount:.2f} (Shipping: ${shipping_fee:.2f})")
        return True

# 测试烂代码
bad_order = {'id': 101, 'type': 'VIP', 'amount': 200}
processor = OrderProcessorBad(bad_order)
processor.process_order() 

“烂点”分析 (Code Smells):

  1. “上帝对象”: OrderProcessorBad 类承担了太多职责(验证、计算、折扣、运费)。
  2. “霰弹式修改” (Shotgun Surgery): 如果需要增加新的订单类型(如“批发订单”),或修改 VIP 订单的折扣规则,我们必须修改这个巨大的 process_order 方法,风险极高。
  3. “条件表达式复杂度”: if/elif/else 嵌套过深,难以阅读和测试。

阶段二:重构策略——引入设计模式

为了解决上述问题,我们将应用**“策略模式 (Strategy Pattern)”**。

策略模式核心思想: 定义一系列算法(策略),将它们封装成独立的类,使得它们可以相互替换,并且客户端代码不需要知道具体执行的是哪一个算法。

目标: 将每一种订单类型的处理逻辑(折扣、运费、税费计算)从主处理器中解耦出来。

1. 定义策略接口 (Strategy Interface)

首先定义一个抽象的策略接口,规定所有订单处理类必须实现的方法。

from abc import ABC, abstractmethod

class OrderStrategy(ABC):
    """定义所有订单处理策略的抽象基类"""
    @abstractmethod
    def calculate_discount_and_shipping(self, amount):
        """返回 (discount, shipping_fee)"""
        pass

    @abstractmethod
    def get_type_name(self):
        pass

2. 实现具体策略 (Concrete Strategies)

为每种订单类型创建具体的处理类。

class StandardOrderStrategy(OrderStrategy):
    def calculate_discount_and_shipping(self, amount):
        # 标准订单:无折扣,固定运费 $10,税率 10%
        discount = 0.0
        shipping = 10.00
        final_price = (amount * 1.10) + shipping
        return discount, shipping, final_price

    def get_type_name(self):
        return "Standard"

class VIPOrderStrategy(OrderStrategy):
    def calculate_discount_and_shipping(self, amount):
        # VIP 订单:15% 优惠,免运费
        discount = amount * 0.15
        shipping = 0.00
        final_price = amount - discount
        return discount, shipping, final_price

    def get_type_name(self):
        return "VIP"

class PromotionOrderStrategy(OrderStrategy):
    def calculate_discount_and_shipping(self, amount):
        # 促销订单:满 $100 减 $20,运费 $5
        discount = 20.00 if amount > 100 else 0.0
        shipping = 5.00 if amount <= 100 else 0.0
        final_price = amount - discount
        return discount, shipping, final_price

    def get_type_name(self):
        return "Promotion"

3. 重构上下文 (Context)

现在,主处理器(Context)的任务变得极其简单:它不再关心具体如何计算,只负责调用选定的策略

class OrderProcessorRefactored:
    # 策略映射表,用于快速查找和实例化策略
    STRATEGY_MAP = {
        "Standard": StandardOrderStrategy(),
        "VIP": VIPOrderStrategy(),
        "Promotion": PromotionOrderStrategy(),
    }

    def __init__(self, order_data):
        self.data = order_data
        self.order_type = order_data.get('type')
        self.amount = order_data.get('amount', 0)
        
        # 运行时选择策略
        self.strategy = self._get_strategy()

    def _get_strategy(self):
        """根据订单类型获取对应的策略实例"""
        strategy_class = self.STRATEGY_MAP.get(self.order_type)
        if not strategy_class:
            raise ValueError(f"Unknown order type: {self.order_type}")
        return strategy_class

    def process_order(self):
        print(f"--- Processing Order {self.data['id']} (Refactored) ---")
        
        if self.amount <= 0:
            print("Error: Amount cannot be zero.")
            return False

        # 核心:执行选定的策略
        discount, shipping, final_amount = self.strategy.calculate_discount_and_shipping(self.amount)
        
        print(f"{self.strategy.get_type_name()} Order processed.")
        if discount > 0:
            print(f"Applied Discount: ${discount:.2f}")
            
        self.data['final_price'] = final_amount
        print(f"Order finalized. Total: ${final_amount:.2f} (Shipping: ${shipping:.2f})")
        return True

# 测试重构后的代码
refactored_order_vip = {'id': 201, 'type': 'VIP', 'amount': 200}
refactored_order_std = {'id': 202, 'type': 'Standard', 'amount': 50}
refactored_order_promo = {'id': 203, 'type': 'Promotion', 'amount': 120}

ProcessorRefactored = OrderProcessorRefactored(refactored_order_vip)
ProcessorRefactored.process_order()

ProcessorRefactored = OrderProcessorRefactored(refactored_order_promo)
ProcessorRefactored.process_order()

阶段三:重构效果对比与总结

特性烂代码 (If/Else)重构后 (策略模式)
可读性低,需要阅读大量分支逻辑高,主流程清晰,逻辑解耦
可扩展性极差,增加新订单类型需修改主类极好,只需新建一个策略类并更新 STRATEGY_MAP
可维护性高风险,修改一处可能影响其他分支低风险,修改特定策略不影响其他部分
可测试性困难,需要构造复杂的输入来覆盖所有分支简单,每个策略类都可以独立进行单元测试
设计模式策略模式 (Strategy Pattern)

重构的价值

通过引入策略模式,我们将“做什么”OrderProcessorRefactored 负责流程控制)和“如何做”(各个 OrderStrategy 负责具体算法)完美分离。这使得代码更符合开闭原则(Open/Closed Principle):对扩展开放,对修改关闭。这正是代码重构艺术的精髓所在。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hefeng_aspnet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值