Introduction
I was recently working on a 2.0 Framework project where we had many types of related objects. However, we needed to ensure that there were not multiple instances of the same object in memory. Usually, the GOF Proxy pattern is used to hide or control access to an object, but we can also use it to define relationships between objects.
The structure of a family and the resulting relationships between family members roughly correlate with the types of relationships we were trying to build between objects. Let's say we have a person, Bill, who is father to Mary and brother to Peter. Peter is an uncle to Mary, but he is also a brother to Bill. The trick is how to represent this in our code.
First, let's look at the wrong way to tackle this so you can see why we needed the Proxy pattern.
Bad Design of Proxy pattern
Here's our Person class.
class BetterDesignPerson
{
private string _Name;
private int _Age;
private Collection<BetterDesignRelative> _Relatives;
public BetterDesignPerson(string name, int age)
{
_Name = name;
_Age = age;
_Relatives = new Collection<BetterDesignRelative>();
}
public int Age
{
get { return _Age; }
set { _Age = value; }
}
public string Name
{
get { return _Name; }
set { _Name = value; }
}
internal Collection<BetterDesignRelative> Relatives
{
get { return _Relatives; }
}
}
And here's our BadDesignRelative class: Can you see what is wrong with the following implementation?
class BetterDesignRelative : BetterDesignPerson
{
private string _Relation;
public BetterDesignRelative(string name, int age, string relation)
: base(name, age)
{
_Relation = relation;
}
public string Relation
{
get { return _Relation; }
set { _Relation = value; }
}
}
Even though Bill "is" a father to Mary and we set up the relationship appropriately through inheritance, we run into a problem when Bill has a birthday, and his age changes as below.
static public void Go()
{
BetterDesignPerson mary = new BetterDesignPerson("Mary", 5);
BetterDesignPerson bill = new BetterDesignPerson("Bill", 28);
mary.Relatives.Add(new BetterDesignRelative("Bill", 28, "Father"));
bill.Age = 29;
}
We actually have two "Bills" in memory.
Bill number 1: Bill.Age == 29
Bill number 2: Mary.Relatives[0].Age == 28
Mary's first and only relative is her father, Bill. Because Bill is not himself, this implementation is not correct, and so we have to start from scratch.
Join the conversation! Your thoughts help the community grow.