Ò
Ò»Ê×Ê«
#This is a real world problem I met.
#
#We have a database containing serveral tables, like : user, role,
organization. Each 2 of them has m:n relationships. These relations
are stored in association tables.
#
#Not we have to load all these data in memory to gain higher
performances. We create 3 classes , User, Role, Organization, to hold
these data.
#
#The question is : should I implement "add/delete/update" as methods
of User, or should I add another class UserManager?
#----------------
# Choice 1
#----------------
user_dict = {}
role_dict = {}
class User:
on_del_funcs = []
roles = []
def del(self):
user_dict.pop(self.name)
for f in self.on_del_funcs:
f(self)
# Using Observer Pattern to notify this user is deleted.
def addUserDelListener(self, on_del_func):
on_del_funcs.append(on_del_funcs)
def delUserDelListener(self, on_del_func):
on_del_funcs.remove(on_del_func)
class Role:
users = []
def addUsser(self, user):
self.users.append(user)
user.roles.append(self)
users.addUserDelListener(self.onUserDel)
def onUserDel(self, user):
self.users.remove(user)
user.delUserDelListener(self.onUserDel)
#----------------
# Choice 2
#----------------
class UserManager:
users = []
@classmethod
def delUser(cls, user):
cls.users.remove(user)
RoleManager.onUserDel(user)
class RoleManager:
roles = []
@classmethod
def onUserDel(cls, user):
for r in cls.roles.items():
r.users.remove(user)
# These codes are not complete, but that's enough to show my question.
# The first choice, which use Observer Pattern, has a very big
problem.
# When calling addUserDelListener, user got not only a callback
function, it
# also add reference count of role. So when we want to delete a
role. We have
# to carefully remove all *listener* hold by other objects, otherwise
this role
# will never be garbage collected.
# Not a big problem for only 2 classes. But when there are 10
*subject* classes which
# Role want to *observe*, 10 listeners has to be removed when delete a
role.
# And if these *subject* have 5 different types of events, then 50
listeners has
# to be removed.
# Actually I tried this approach once, and it is still a big headache
for 10
# programmers. ( The company I worked at that time hate any change to
so-called
# working code )
# The second choice, which I am using right now, actually has nothing
to do with
# Object Oriented Designing. The manager classes are not real
classes, just
# container of methods. These User/Role classes are only container
of data,
# not behavior.
#
# For many times, I asked my self, "Is it too hard for me to see the
power of
# OO, or I have just never met a problem suitable for a OO resolution?"
#
#We have a database containing serveral tables, like : user, role,
organization. Each 2 of them has m:n relationships. These relations
are stored in association tables.
#
#Not we have to load all these data in memory to gain higher
performances. We create 3 classes , User, Role, Organization, to hold
these data.
#
#The question is : should I implement "add/delete/update" as methods
of User, or should I add another class UserManager?
#----------------
# Choice 1
#----------------
user_dict = {}
role_dict = {}
class User:
on_del_funcs = []
roles = []
def del(self):
user_dict.pop(self.name)
for f in self.on_del_funcs:
f(self)
# Using Observer Pattern to notify this user is deleted.
def addUserDelListener(self, on_del_func):
on_del_funcs.append(on_del_funcs)
def delUserDelListener(self, on_del_func):
on_del_funcs.remove(on_del_func)
class Role:
users = []
def addUsser(self, user):
self.users.append(user)
user.roles.append(self)
users.addUserDelListener(self.onUserDel)
def onUserDel(self, user):
self.users.remove(user)
user.delUserDelListener(self.onUserDel)
#----------------
# Choice 2
#----------------
class UserManager:
users = []
@classmethod
def delUser(cls, user):
cls.users.remove(user)
RoleManager.onUserDel(user)
class RoleManager:
roles = []
@classmethod
def onUserDel(cls, user):
for r in cls.roles.items():
r.users.remove(user)
# These codes are not complete, but that's enough to show my question.
# The first choice, which use Observer Pattern, has a very big
problem.
# When calling addUserDelListener, user got not only a callback
function, it
# also add reference count of role. So when we want to delete a
role. We have
# to carefully remove all *listener* hold by other objects, otherwise
this role
# will never be garbage collected.
# Not a big problem for only 2 classes. But when there are 10
*subject* classes which
# Role want to *observe*, 10 listeners has to be removed when delete a
role.
# And if these *subject* have 5 different types of events, then 50
listeners has
# to be removed.
# Actually I tried this approach once, and it is still a big headache
for 10
# programmers. ( The company I worked at that time hate any change to
so-called
# working code )
# The second choice, which I am using right now, actually has nothing
to do with
# Object Oriented Designing. The manager classes are not real
classes, just
# container of methods. These User/Role classes are only container
of data,
# not behavior.
#
# For many times, I asked my self, "Is it too hard for me to see the
power of
# OO, or I have just never met a problem suitable for a OO resolution?"