mardi 20 mars 2018

How to structure classes with varying capabilities

I'm designing an application in PyQt that uses accounts for specific websites. So I have a base class called Account, and website specific account classes derived from Account such as: GoogleAccount, YouTubeAccount, etc.

Each of these derived Account classes needs to describe if it has the capability to Download, Upload, or both. Basically whether or not download or upload interface methods are implemented for the particular website. So each account instance for a particular website has the same download/upload capability.

I'm trying to figure out how to structure these Account classes that can have a particular mix of Downloadable/Uploadable capabilities. One solution I've come up with is to use the multiple inheritance type pattern from the Interface Segregration Principle:

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

Another super simple solution would be to just add two boolean class attributes

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

    def doDownload(): # doStuff

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

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

To check the download/upload capability (For example, to display all Accounts that are download capable) you would use something like isinstance(account, Downloadable) for the first multiple inheritance solution and account.canDownload for the second boolean solution.

I'm leaning towards the first solution with multiple inheritance. Anybody else have any other suggestions on how to structure classes like this?

Aucun commentaire:

Enregistrer un commentaire