python - 在 ABC 的不同具体实现之间实例化对象选择

标签 python abstract-class

在我的代码中,我目前有一个类 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/

相关文章:

.net - 派生自 C++ 中的 .NET 抽象类,System::IO::TextWriter

python - 来自 J Zelle 教授的 Python Graphics.py 上的 yUP

python - 如何使最后一个 gtk.TreeView 列可调整大小?

python - 如何从经过训练的 Tensorflow 分类器获得类别预测?

java - 当实现仅在一个方法上不同时,建议使用哪种设计模式?

c++ - 使用 boost 序列化抽象类时出错

python - read_csv 将 .1 附加到列名

python - 二维 np.digitize

c# - 没有抽象方法实现的抽象派生类

java - 运行类测试的输出是什么? (Java,抽象类)