如何将类方法重构到抽象基类,拆分逻辑且不改变基类方法签名?
重构抽象基类子类的优化方案
问题背景
现有类current_class的func方法包含A、B两个独立逻辑:逻辑A负责加载大型字典dataset,逻辑B依赖dataset.keys()执行操作。代码如下:
class current_class: def func(self): # 执行A相关逻辑 # 执行B相关逻辑
需要创建仅包含逻辑A的another_class:
class another_class: def func(self): # 执行A相关逻辑
核心要求:
- 两个类均继承抽象基类
base - 逻辑A在基类中实现,避免代码冗余
current_class无需重复加载dataset- 保证子类方法签名一致
现有方案及缺陷
方案1
from abc import ABC, abstractmethod class base(ABC): @abstractmethod def func(self): pass def func_A(self): # 执行A相关逻辑并获取dataset return dataset.keys() class current_class(base): def func_B(self, keys): # 执行B相关逻辑 def func(self): keys = self.func_A() self.func_B(keys) class another_class(base): def func(self): _ = self.func_A() # 返回值未使用
缺陷:another_class调用func_A时返回的keys未被使用,存在不必要的资源开销。
方案2
from abc import ABC, abstractmethod class base(ABC): @abstractmethod def func(self): pass class current_class(base): def func_A(self): # 执行A相关逻辑并获取dataset return dataset.keys() def func_B(self, keys): # 执行B相关逻辑 def func(self): keys = self.func_A() self.func_B(keys) class another_class(base): def func_A(self): # 执行与current_class相同的A逻辑,无返回值 def func(self): self.func_A()
缺陷:func_A的逻辑在两个子类中重复实现,导致代码冗余,后期维护成本高。
优化方案:属性缓存+按需调用
利用基类的属性缓存机制处理逻辑A,子类按需触发加载并执行对应逻辑,既消除冗余又避免资源浪费:
from abc import ABC, abstractmethod class base(ABC): def __init__(self): self._dataset = None # 缓存加载后的大型字典 def _load_dataset(self): # 这里编写逻辑A:加载大型字典dataset # 示例:self._dataset = {"user1": "data1", "user2": "data2"} pass @property def dataset(self): # 懒加载:仅在首次访问时执行逻辑A if self._dataset is None: self._load_dataset() return self._dataset @abstractmethod def func(self): pass class current_class(base): def _execute_func_B(self): # 逻辑B直接使用缓存的dataset的keys keys = self.dataset.keys() # 编写逻辑B的具体操作 pass def func(self): # 访问dataset属性自动触发逻辑A,再执行逻辑B self._execute_func_B() class another_class(base): def func(self): # 仅触发逻辑A:访问dataset属性完成加载 _ = self.dataset
方案优势
- 无代码冗余:逻辑A(加载dataset)仅在基类中实现一次,所有子类共享
- 性能优化:
dataset采用懒加载+缓存机制,current_class多次使用也不会重复加载 - 资源无浪费:
another_class仅触发加载操作,无多余返回值开销 - 扩展性强:后续若
another_class需要逻辑B,可直接复用_execute_func_B方法或自行实现 - 符合抽象基类要求:两个子类均实现了抽象方法
func,签名完全一致
可选简化方案
如果对返回值的轻微开销可以接受,也可以采用更简洁的实现:
from abc import ABC, abstractmethod class base(ABC): def func_A(self): # 执行逻辑A,加载并返回dataset dataset = {} # 实际加载逻辑 return dataset @abstractmethod def func(self): pass class current_class(base): def func_B(self, dataset): # 逻辑B使用dataset.keys() keys = dataset.keys() # 编写逻辑B操作 pass def func(self): dataset = self.func_A() self.func_B(dataset) class another_class(base): def func(self): self.func_A() # 仅执行逻辑A,忽略返回值
该方案代码更简洁,仅需在基类实现func_A,子类按需调用即可,返回值的轻微开销在多数场景下可忽略。
内容的提问来源于stack exchange,提问作者structuralengin
相关产品推荐
相关产品推荐

