为多个具体实现定义API

问题描述 投票:0回答:1

我尝试实现多个共享相同 API 的具体类。这些类之间的基本功能是相同的,但它们支持不同类型的配置(在共享配置之间)。我希望这些具体类之间的实现尽可能分开。

因此我想出了一个(抽象)基类来定义 API,但我不确定如何定义函数参数。

  1. 包含所有可能性的通用配置

    • (+) 所有实现都使用相同的 API。

    • (-) API 建议某些不受支持的配置。 (不过可能是在未来)。

      也许我需要在文档中解决这个问题,并且/或者甚至在使用不当的情况下引发异常。

    • (-) 如果添加新的配置属性,其他现有的具体类不会处理这个新属性。

    @dataclass
    class CommonCfg:
        cfg_1: Optional[int] = None
        cfg_2: Optional[int] = None
        cfg_3: Optional[int] = None
    
    class AbstractA:
        @abstractmethod
        def func_z(self, cfg: CommonCfg):
    
    class B(AbstractA):
        def func_z(self, cfg: CommonCfg):
            # Does not use `cfg_3`.
    
    class C(AbstractA):
        def func_z(self, cfg: CommonCfg):
            # Does not use `cfg_2`.
    
    
  2. 基类的通用签名

    class AbstractA:
        def func_z(self, *args, **kwargs):
            # Or expect `CommonCfg` which only contains common config parameters (e.g. `cfg_1`)
    

    对于

    func_z
    ClassB
    ClassC
    分别期望其具体的
    CfgB
    CfgC

在完美的场景中,我可以交换不同具体实现的对象(至少只要它们的通用配置相关)。 例如

...
b = ClassB()
c = ClassC()

cfg = CommonCfg()
b.func_z(cfg)
# I would like to have the least amount of hassle replacing it, e.g. with:
# c.func_z(cfg)

python inheritance design-patterns interface
1个回答
0
投票

一种可能的解决方案是将基本功能委托给基类。这样,如果您向

CommonCfg
对象添加其他参数,则不必更新基类方法。代码可能看起来像这样:

class AbstractA:
    def func_z(self, cfg: CommonCfg):
        # Do some work using cfg

class B(AbstractA):
    def func_z(self, cfg: CommonCfg):
        super().func_z(cfg)
        # Do some additional work

class C(AbstractA):
    def func_z(self, cfg: CommonCfg):
        super().func_z(cfg)
        # Do some additional work

这还可以让您检查

cfg
对象是否受支持 在调用基本方法之前调用方法。

对于不支持的配置,您已经提到了一个应该为您提供最大灵活性的解决方案。只需为每种方法添加详细说明不支持哪些配置的文档就应该给出任何 体面的用户有足够的信息来正确使用 API。引发异常还可以帮助用户检测代码中的任何错误。

© www.soinside.com 2019 - 2024. All rights reserved.