Re: Looking for Design Input
- From: "Edward Stow" <ed.stow@xxxxxxxxx>
- Date: 7 Mar 2007 02:19:08 -0800
On Mar 7, 9:50 am, "Malbs" <ssefl...@xxxxxxxxxxxxx> wrote:
I have a probelm I'm trying to solve. I was trying to thing of the same
problem in a different domain to discover if maybe there is some sort of
pattern I can apply... I was struggling to come up with the same design
problem in a different domain when it hit me. The common mailing list.
think of a simple mailing list system design. Sorry to make people think in
text, but here we go.
MailingList
addMember: aMember - adds a member
removeMember: aMember - removes a member
includesMember: aMember - tests for membership.
selectMembers: aBlock
MailingList class
repository
^Repository ifNil: [ Repository := OrderedCollection new ]
Member
username - gets and sets username ivar
password - gets and sets password ivar
emailAddress - gets and sets password ivar
subscriptions - returns a list of all the subscribed mailing lists.
^MailingList repository select: [ :ea | ea includesMember: self ]
The design problem is, that for each subscription a Member may have
different preferences. In one mailing list they may want a digest mode,
however in another mailing list they may prefer a threaded or per-message
mode.
So I started thinking.. is it a decorator pattern I wanted to use. Wrap up
the Member object in a new object which also contains the Options for the
member, and delegated all of the Member protocols to its internal Member
object... I didn't really feel like that was the correct pattern to apply
here.. so this is what I came up with and I'm wondering what other people
think of it from an OO/Smalltalk/Eww Yuck point of view
Created a new class:
MailingListOptions
initializeWithMember: aMember mailinglist: aMailingList - Private, sets
the two ivars
member - returns the member this is for
mailinglist - returns the mailing list its for
beDigest
beStandard
isDigest
isStandard
then we modify the add and remove methods of MailingList
addMember: aMember
(self includesMember: aMember) ifTrue: [ ^aMember ]
memberOptions at: aMember put: (MailingListOptions member: aMember
mailinglist: self)
members add: aMember.
removeMember: aMember
(self includesMember: aMember) ifFalse: [ ^aMember ]
memberOptions removeKey: aMember.
members remove: aMember.
and introduce a new method to get the options:
optionsForMember: aMember
^memberOptions at: aMember
so now a person can go to their subscription of PHP-Dev, and:
(mailinglist optionsForMember: me) beDigest.
then when it comes time to generate the digest email:
mailinglist selectMembers: [ :ea | (mailinglist optionsForMember: ea)
isDigest ].
gets me a list of members who have set their preference to digest mode.
Now I realise this doesn't cover such things as tracking when digest mode
was turned on, so as to not send messages the user has already received in
standard mode, but thats beyond the scope of this :P
So what I'm interested in?
Has anyone else had to implement a similar design summarised with:
A Member can belong to many MailingLists, and that person may have different
MailingListOptions for each MailingList.
And how did you do it? Am I on the right track, wrong track? I don't know
any Smalltalkers IRL that I can talk to about this. Hell I don't know anyone
who really knows OO that I can talk to about this. Everyone I work with uses
classes as a way to have c code with namespaces.
This seems a lot of work to only records member options: Why not:
MailingList
ivar
memberOptions a Dictionary
key - member
value - #digest || #normal
Appropiate methods to set and retrieve the member state would need to
be added.
I would make the Repository a class even if you only need a singleton.
To further elaboration the design you need to consider how you handle
the message forwarding operations.
--
.
- References:
- Looking for Design Input
- From: Malbs
- Looking for Design Input
- Prev by Date: Re: D6 Visual Designer align commands are unintuitive
- Next by Date: Re: Looking for Design Input
- Previous by thread: Looking for Design Input
- Next by thread: Re: Looking for Design Input
- Index(es):
Relevant Pages
|