在Python项目开发过程中,当业务逻辑逐渐复杂时,原本的面向过程代码往往会出现函数冗余、逻辑分散、修改成本高的问题,此时采用面向对象的思想重构代码,能够有效提升整体代码质量。
面向对象重构的核心思路
1. 识别业务实体封装成类
首先需要从现有代码中梳理出核心的业务实体,将实体相关的属性、操作封装到同一个类中,避免属性和操作分散在不同的函数里。比如电商系统中的商品、订单、用户都是典型的业务实体,适合封装为独立的类。
2. 提取公共逻辑实现继承复用
如果存在多个类有重复的属性或方法,可以将这些公共部分提取到父类中,让子类通过继承获取这些能力,减少重复代码的编写。比如不同类型的支付方式都可以继承基础支付类,复用支付校验的公共逻辑。
3. 定义统一接口实现多态扩展
对于同一类操作的不同实现,可以定义统一的抽象接口,不同实现类遵循接口规范编写逻辑,后续新增实现时不需要修改原有调用代码,降低扩展成本。
重构前后代码对比示例
以下是一个简单的用户积分计算场景,先看重构前的面向过程代码:
# 重构前的面向过程代码
def calc_normal_user_score(user_info):
score = user_info['base_score']
score += user_info['login_days'] * 2
if user_info['is_vip']:
score *= 1.5
return score
def calc_vip_user_score(user_info):
score = user_info['base_score']
score += user_info['login_days'] * 3
score += user_info['invite_count'] * 10
return score
user1 = {'base_score': 100, 'login_days': 20, 'is_vip': False}
user2 = {'base_score': 150, 'login_days': 30, 'is_vip': True, 'invite_count': 5}
print(calc_normal_user_score(user1))
print(calc_vip_user_score(user2))
上述代码的问题在于用户属性和积分计算逻辑分散,新增用户类型时需要新增函数,修改计算规则需要改动多个函数。下面是面向对象重构后的代码:
# 重构后的面向对象代码
from abc import ABC, abstractmethod
class User(ABC):
def __init__(self, base_score, login_days):
self.base_score = base_score
self.login_days = login_days
@abstractmethod
def calc_score(self):
pass
class NormalUser(User):
def __init__(self, base_score, login_days, is_vip):
super().__init__(base_score, login_days)
self.is_vip = is_vip
def calc_score(self):
score = self.base_score + self.login_days * 2
if self.is_vip:
score *= 1.5
return score
class VipUser(User):
def __init__(self, base_score, login_days, invite_count):
super().__init__(base_score, login_days)
self.invite_count = invite_count
def calc_score(self):
score = self.base_score + self.login_days * 3 + self.invite_count * 10
return score
user1 = NormalUser(100, 20, False)
user2 = VipUser(150, 30, 5)
print(user1.calc_score())
print(user2.calc_score())
重构后代码质量提升表现
- 可读性提升:用户属性和对应的积分计算逻辑封装在各自的类中,代码结构清晰,新人接手时能快速理解每个类的职责。
- 可维护性提升:修改普通用户的积分计算规则只需要改动
NormalUser类的calc_score方法,不会影响其他用户类型的逻辑。 - 可扩展性提升:新增比如企业用户类型时,只需要新增
EnterpriseUser类继承User基类,实现calc_score方法即可,不需要修改原有调用代码。 - 复用性提升:如果多个用户类型有公共的属性或方法,可以提取到
User基类中,避免重复编写相同逻辑。
重构注意事项
重构时不要一次性改动所有代码,建议先对局部模块进行重构,编写对应的单元测试保证重构后功能正常,再逐步推广到整个项目。同时要避免过度设计,不需要为了用面向对象而强行拆分类,只有当代码出现维护困难、重复逻辑多的问题时,再考虑用面向对象的方式重构。