public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class PersonInformation
{
private readonly Person myPerson;
public PersonInformation(Person person)
{
myPerson = person;
}
public Person Person
{
get { return myPerson; }
}
}
internal class Processor
{
private readonly PersonInformation myPersonInformation;
public Processor(PersonInformation personInformation)
{
myPersonInformation = personInformation;
}
public int Process()
{
switch (myPersonInformation.Person.Name)
{
case "Mike":
return 1;
case "Sally":
return myPersonInformation.Person.Age > 30 ? 2 : 3;
}
return myPersonInformation.Person.Age < 20 ? 0 : 1;
}
}
Consider PersonInformation class above. We wanted to decouple it from Person class and make it store Name and Age itself. However, we had a lot of usages like in Processor.Process, where Person property was being used to access Name and Age. How would we do it?
First, we use Generate (Alt-Ins) and select Delegating Members to generate Name and Age properties in PersonInformation class:
public string Name
{
get { return myPerson.Name; }
set { myPerson.Name = value; }
}
public int Age
{
get { return myPerson.Age; }
set { myPerson.Age = value; }
}
Then we change Person Property to return PersonInformation instead. Since there are all required properties already, usages are not broken. They are now routed through delegating members and use Name and Age properties of PersonInformation:
public PersonInformation Person
{
get { return this; }
}
And here magic happens, we use Inline Property refactoring to get rid of the property!
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class PersonInformation
{
private readonly Person myPerson;
public PersonInformation(Person person)
{
myPerson = person;
}
public string Name
{
get { return myPerson.Name; }
set { myPerson.Name = value; }
}
public int Age
{
get { return myPerson.Age; }
set { myPerson.Age = value; }
}
}
internal class Processor
{
private readonly PersonInformation myPersonInformation;
public Processor(PersonInformation personInformation)
{
myPersonInformation = personInformation;
}
public int Process()
{
switch (myPersonInformation.Name)
{
case "Mike":
return 1;
case "Sally":
return myPersonInformation.Age > 30 ? 2 : 3;
}
return myPersonInformation.Age < 20 ? 0 : 1;
}
}
Look how Processor now uses Name and Age directly on PersonInformation class and has no idea about Person class used inside! Now the fact that PersonInformation uses Person is implementation detail and we can change it any way we like.
Refactor With Pleasure!
3 comments:
Very elegant indeed! There's a pattern in there somewhere. Bringing the values of the replacing type into the type that is to be removed and then inlining. It reminds me of working with equations in mathematics where you make a substitution so as to simplify and then cancel down to reveal a more elegant result. But hey, it's a long time since I've done any maths!!
Hi there not sure where to ask this question but I was wondering when Resharper 4.5 M1 is due for release? I saw that it was initially supposed to be October 13th but there hasn't been a mention of it. Lately I notice it really slows down the system that I often have to disable the addin when debugging then enable it back on when coding
Just following you from Tess blog :-) I see that the website is up now, link was broken because of change in name server so you should be able to download sos2.dll from
http://debuggingblog.com/wp
Post a Comment