Skip to content

Instantly share code, notes, and snippets.

@mindplay-dk
Created January 3, 2012 17:37
Show Gist options
  • Save mindplay-dk/1555995 to your computer and use it in GitHub Desktop.
Save mindplay-dk/1555995 to your computer and use it in GitHub Desktop.
short rant about a shortcoming of OOP languages in general
// let's say we have a house:
$house = new House();
// let's say the house has a door:
$door = new Door();
// why does it take two steps to add the door to the house?
$door->house = $house;
$house->doors->add($door);
// this is so redundant and error-prone, it makes me want to scream.
//
// why do I have to maintain the house-reference from the door, and
// the list of doors on the house, separately?
//
// a one-to-many relationship such as this, as well as many-to-many
// relationships (with lists on both sides) should be solved at the
// language-level - rather than solving it repeatedly in every case.
//
// and sure, you could make the list of doors private, and make the
// house-reference from the door private, and add methods like addDoor,
// removeDoor, setHouse, etc. - but that only solves the problem for
// houses and doors; not for relationships in general.
//
// $door->house = $house should IMPLY $house->doors->add($door)
//
// and $house->doors->add($door) should IMPLY $door->house = $house
//
// it seems like this is a general problem with OOP languages all-round?
//
// for databases, many people have realized that graph-databases solve
// this problem most elegantly, by maintaining two-sided relationships
// atomically, as a single unit.
//
// how come this issue has to be addressed by ORMs - for example, the
// inverse-mapping attribute in Hibernate mappings; rather than fixing
// this obvious shortcoming at the language-level??
// This is completely fictive and probably wrong in more than one way.
// Just a quick demonstration of the direction I'm thinking in right now...
class House
has many Door(Doors)
{
public IList<Door> Doors { get; set; }
}
class Door
belongs to House(Owner).Doors
has many Key(Keys).OpensDoors
{
public House Owner { get; set; }
public IList<Key> Keys { get; set; }
}
class Key
has many Door(OpensDoors).Keys
{
public IList<Door> OpensDoors { get; set; }
}
var house = new House();
var door = new Door();
door.Keys.Add(key); // implies: key.OpensDoors.Add(door);
var key = new Key();
house.Doors.Add(door); // implies: door.Owner = house;
// and vice-versa:
key.OpensDoors.Remove(door); // implies: door.Keys.Remove(key)
door.Owner = null; // implies: house.Doors.Remove(door)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment