Relationship properties
Feb. 1st, 2007 06:45 pmMy brain is drawing a blank on this:
Let's say I have a class Group and a class Person, where there's an n:m relationship between these. It's simple to say that Group could have an attribute "members" which is a collection of Persons, or Person could have an attribute "groups" which is a collection of Groups.
The problem then is that there's no relationship properties there. I can't easily describe for how long the person has been a member of the group, when that membership expires, etc. It seems to me that these type of properties ought to be describable in an elegant way. Perhaps as a characteristic of the array? I want to do this ideally in a way that for items that have no meaningful characteristics I can just use a standard Array class of some sort, but that when properties come up, I want to be able to add them silently so that existing code can continue to just work.
Let's say I have a class Group and a class Person, where there's an n:m relationship between these. It's simple to say that Group could have an attribute "members" which is a collection of Persons, or Person could have an attribute "groups" which is a collection of Groups.
The problem then is that there's no relationship properties there. I can't easily describe for how long the person has been a member of the group, when that membership expires, etc. It seems to me that these type of properties ought to be describable in an elegant way. Perhaps as a characteristic of the array? I want to do this ideally in a way that for items that have no meaningful characteristics I can just use a standard Array class of some sort, but that when properties come up, I want to be able to add them silently so that existing code can continue to just work.
no subject
Date: 2007-02-02 03:05 am (UTC)User.is_expired($group)
User.expires_on($group)
User.member_since($group)
Group.is_expired($user)
Group.expires_on($user)
Group.member_since($user)
This has several nice properties:
- The Membership stays out of the public API.
- Using explicitly named methods makes for good code-readability:
if (! $user->is_expired($group)) { ... }
- It's easy to unit test.
It has at least the following deficiency:
- You can get into a situation where passing users and groups around together to access membership data becomes tedious. If/when that happens you can refactor to contextful objects with a simpler API:
User.__construct($group)
User.is_expired()
User.expires_on()
User.member_since()
etc.