python: how to design a container with elements that must reference their container

Posted by Luke404 on Stack Overflow See other posts from Stack Overflow or by Luke404
Published on 2010-04-15T15:39:21Z Indexed on 2010/04/15 16:33 UTC
Read the original article Hit count: 386

Filed under:
|
|

(the title is admittedly not that great. Please forgive my English, this is the best I could think of)

I'm writing a python script that will manage email domains and their accounts, and I'm also a newby at OOP design. My two (related?) issues are:

  1. the Domain class must do special work to add and remove accounts, like adding/removing them to the underlying implementation
  2. how to manage operations on accounts that must go through their container

To solve the former issue I'd add a factory method to the Domain class that'll build an Account instance in that domain, and a 'remove' (anti-factory?) method to handle deletions.

For the latter this seems to me "anti-oop" since what would logically be an operation on an Account (eg, change password) must always reference the containing Domain. Seems to me that I must add to the Account a reference back to the Domain and use that to get data (like the domain name) or call methods on the Domain class.

Code example (element uses data from the container) that manages an underlying Vpopmail system:

class Account:
    def __init__(self, name, password, domain):
        self.name = name
        self.password = password
        self.domain = domain
    def set_password(self, password):
        os.system('vpasswd %s@%s %s' % (self.name, self.domain.name, password)
        self.password = password

class Domain:
    def __init__(self, domain_name):
        self.name = domain_name
        self.accounts = {}
    def create_account(self, name, password):
        os.system('vadduser %s@%s %s' % (name, self.name, password))
        account = Account(name, password, self)
        self.accounts[name] = account
    def delete_account(self, name):
        os.system('vdeluser %s@%s' % (name, self.name))
        del self.accounts[name]

another option would be for Account.set_password to call a Domain method that would do the actual work - sounds equally ugly to me.

Also note the duplication of data (account name also as dict key), it sounds logical (account names are "primary key" inside a domain) but accounts need to know their own name.

© Stack Overflow or respective owner

Related posts about python

Related posts about oop