2

I have a settings object that contains some generic settings. These settings will change for each user. I'm wondering what would be the best way to code this. My current method is this:

class Settings(object):

    def __init__(self, user=None):

        if user and not isinstance(user, users.User):
            raise TypeError('must be a User object')

        self.user = user

    @property
    def title(self):

        if self.user:
            return 'user setting'

        return 'generic setting'

Given that there will be a few methods in Settings, having to run that if statement each time kinda sucks.

I was considering having a UserSettings class that extends Settings to override the defaults and provide the user specific settings. Though, I've heard that overriding methods is bad OOP design. Which leads me to option 2...

I then thought of creating UserSettings but it won't extend Settings. It'll instead wrap it and I'll have something like:

class UserSettings(object):

    def __init__(self, user=None):

        if user and not isinstance(user, users.User):
            raise TypeError('must be a User object')

        self.user     = user
        self.settings = Settings()

    @property
    def title(self):

        return 'user setting'

So I can then do:

print user_settings.title # get the user title
print user_settings.settings.title # get the generic title

How should I code this?

dave
  • 7,717
  • 19
  • 68
  • 100
  • 3
    "Though, I've heard that overriding methods is bad OOP design" -- that's nonsense. – Ferdinand Beyer Aug 26 '11 at 10:47
  • So you'd go for the second option? Subclass the `Settings` object and override the User specific settings? – dave Aug 26 '11 at 10:50
  • Some thoughts: (1) Do you really need properties for constant settings? Why don't you just use attributes (`self.value = 42`)? (2) How are *Settings* objects created? Do you create one once and keep it available for all parts that need to access it or are new objects created on the fly all the time? (3) If there is a user-defined setting, do you also need to access the generic setting sometimes? – Ferdinand Beyer Aug 26 '11 at 11:07
  • The data is dynamically pulled from a database when needed. That's why `@property` is being used. It'll be created once and kept available. No, I shouldn't need to access the generic setting for each user. On the rare occasion I do, I can just initialise the `Settings` object, I suppose. – dave Aug 26 '11 at 11:49

1 Answers1

3

Overriding methods is not only not bad OOP design, it's the basis for subtype polymorphism, which is core to OOP, and a common way to get rid of the need for such conditional checks.

There are certainly times when you should prefer composition to inheritance, but it's not clear from your description that there's anything wrong with making this a subclass.

Community
  • 1
  • 1
Don Roby
  • 40,677
  • 6
  • 91
  • 113
  • Cheers for the 'prefer composition to inheritance' link. Enough info in that thread to point me in the right direction. – dave Aug 26 '11 at 12:10