如何构建具有不同功能的类

Posted

技术标签:

【中文标题】如何构建具有不同功能的类【英文标题】:How to structure classes with varying capabilities 【发布时间】:2018-08-29 01:56:39 【问题描述】:

我正在 PyQt 中设计一个使用特定网站帐户的应用程序。所以我有一个名为 Account 的基类,以及从 Account 派生的网站特定帐户类,例如:GoogleAccount、YouTubeAccount 等。

这些派生帐户类中的每一个都需要描述它是否具有下载、上传或两者兼而有之的能力。基本上是否为特定网站实现了下载或上传接口方法。因此,特定网站的每个帐户实例都具有相同的下载/上传功能。

我试图弄清楚如何构建这些帐户类,这些类可以具有特定的可下载/可上传功能组合。我想出的一种解决方案是使用接口隔离原则中的多重继承类型模式:

class Downloadable(metaclass=ABCMeta):
    @abstractmethod
    def doDownload(): raise NotImplementedError("Reimplement me") 

class Uploadable(metaclass=ABCMeta):
    @abstractmethod
    def doUpload(): raise NotImplementedError("Reimplement me") 

class YoutubeAccount(Account, Downloadable):
    """ All accounts from this website implement download capability """
    def doDownload(): # dostuff
    def otherMethods(): pass

class GoogleAccount(Account, Downloadable, Uploadable):
    """ All accounts on this website implement both download and upload capability """
    def doDownload(): # doStuff
    def doUpload(): # doStuff
    def otherMethods(): pass

另一个超级简单的解决方案是添加两个布尔类属性

class YoutubeAccount(Account):
    DOWNLOADABLE = True
    UPLOADABLE = False

    def doDownload(): # doStuff

class GoogleAccount(Account):
    DOWNLOADABLE = True
    UPLOADABLE = True

    def doDownload(): # doStuff
    def doUpload(): # doStuff

要检查下载/上传功能(例如,显示所有可以下载的帐户),您可以使用 isinstance(account, Downloadable) 来表示第一个多重继承解决方案,使用 account.DOWNLOADABLE 表示第二个布尔解决方案。

我倾向于使用多重继承的第一个解决方案。还有其他人对如何构造这样的类有任何其他建议吗?

【问题讨论】:

【参考方案1】:

如果您只有少数派生自 Account 的类,我认为 python 方式将是选项 2。

但是,如果它违反了您担心的 DRY 原则(因为这些类属性可以从相应的方法派生),您可以在 Account 基类上添加 canDownloadcanUpload 方法并让它们返回 @987654325分别是@和hasattr(self, "doUpload")

【讨论】:

以上是关于如何构建具有不同功能的类的主要内容,如果未能解决你的问题,请参考以下文章

如何让一个向量接受具有相同基类的 2 个不同的类?

2 个具有相同功能但变量名不同的 C++ 类 - 使用哪种模式?

如何从不同的类运行关闭视图功能?

如何解决具有不同包装常春藤类型的sbt中的依赖关系?

具有覆盖构建功能的类扩展 StatelessWidget 和具有我自己的功能的常规类有啥区别

如果我有 2 个具有相同视图但逻辑不同的 Angular 组件,如何正确构建代码?