在我的代码中,我目前有一个类 Obj
,实现了一些低级功能,其中没有什么花哨的。现在,我需要添加 Obj
的第二个实现。实例化哪个实现应该根据一些属性来决定,并在实例化时检查。
我想出的解决方案是有一个抽象类_absObj
,以及它的两个实现,_Obj1
和_Obj2
。我仍然想在 API 级别仅呈现一个 Obj
类,因此我像这样重新实现了 Obj
:
class Obj:
__new__(cls, stuff):
if _check_something(stuff):
return _Obj1(stuff)
else:
return _Obj2(stuff)
这工作正常,但我发现一些不便:
- [minor]
Obj
没有记录的方法。也许这实际上是一个优势。 - [major]
Obj
不是absObj
的子类,即使从它实例化的每个对象都派生自抽象类。 - [major] 在测试中,我需要经常模拟
Obj
,但我无法模拟它的任何方法,它没有!我只能模拟其实现之一,这是脆弱的,因为我可能会更改实现,或者实例化的实现可能会发生变化。
有没有更聪明的解决方案?如果解决方案意味着转储一些 oop 噪声,那就更好了。
最佳答案
我会这样写。 AbsObj
将是唯一的“公共(public)”类。它的实现将由 AbsObj#create
选择并返回。
from abc import ABCMeta, abstractmethod
class AbsObj(metaclass=ABCMeta):
@abstractmethod
def foo(self):
'''Document this.'''
pass
@staticmethod
def create(stuff):
'''
All the user needs to know is that create returns an AbsObj.
The specific implementation shouldn't matter.
'''
if stuff:
return Obj1(stuff)
else:
return Obj2(stuff)
class Obj1(AbsObj):
def foo(self):
print('number 1')
class Obj2(AbsObj):
def foo(self):
print('number 2')
AbsObj.create(True).foo
AbsObj.create(False).foo
关于python - 在 ABC 的不同具体实现之间实例化对象选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53558521/