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

时间:2018-11-30 13:29:28

标签: 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)

这很好,但给您带来一些不便:

  • [未成年人] Obj没有记录的方法。也许这实际上是一个优势。
  • [主要] Obj不是absObj的子类,即使从它实例化的每个对象都派生自抽象类。
  • [主要]在测试中,我经常需要模拟Obj,但是我无法模拟其任何方法,没有方法!我只能模拟它的一个脆弱的实现,因为我可能会更改实现,或者实例化的实现可能会更改。

有没有更智能的解决方案?如果解决方案意味着倾销一些oop噪声,那就更好了。

2 个答案:

答案 0 :(得分:2)

我会这样写。 copyOfStream将是唯一的“公共”类。其实现将由AbsObj选择并返回。

AbsObj#create

答案 1 :(得分:1)

可能的解决方法如下:

class Obj(ABC):
    @abstractmethod
    def f1(...):
        pass

    @abstractmethod
    def f1(...):
        pass

    @classmethod
    def factory(stuff):
        if _check_something(stuff):
             return _Obj1(stuff)
        else:
             return _Obj2(stuff)

_Obj1_Obj2源自Obj本身。即使我不确定所有含义,这也确实有效。