There is a very interesting conversation going on at the Test-Driven Development list about Eschewing Fundamental Types. Basically, how many times have you done:
public class Person
{
//...
public string FirstName
{
get{return firstName;}
}
public string LastName
{
get{return lastName;}
}
}
and then how many times has the requirement changed so you have to provide a full name representation? Or Last, First? Or handle Maiden names?
John Roth got the ball rolling with:
It’s that simple: the fundamental language types, and the basic language libraries, do not, and let me repeat that, do not represent any concepts that your application actually needs. At best they represent bizzare oversimplifications of those concepts that can’t be told apart by the type checking mechanism.
It’s a fascinating concept, and one that I was amazed how often I skipped over. If I see two properties with the same suffix, it often raises a flag that maybe they want to be their own class. But for some reason that same flag never gets raised with names and other fundamental properties of common classes.
So, the solution is to tweak your Spidey-Sense to recognize this duplication. In the above example, we would have:
public class Person
{
public Name Name
{
get{return name;}
}
}
public class Name
{
public string FirstName
{
get{return firstName;}
}
public string LastName
{
get{return lastName;}
}
}
Which allows us to grow the name class as our app wants it.
A counter-argument raised by Ron Jeffries was YAGNI. What story caused you to want Name to be a class? What duplication triggered the Extract Class refactoring?
I would argue that as soon as you ask for more than a simple name, (and maybe not until it’s more than a first name and last name) that you should move it into a Name object. Moving it sooner could get you hitting against YAGNI.
I guess, like a lot of things, it comes down to experience and how badly your spidey-sense is tingling.
What do you all think?