One of the problem we may get into as programmers is that requirements often change and we don't always have a bunch of time to make sure everything fits. In most instances, customers don't really care about how well your object model conforms to OOP guidelines, they care about how well your software works, when they can have it and how much it costs. So many times we start cramming stuff in when we are in a hurry and our classes get a little messy.
I'm going to demonstrate how to clean up a class using a refactoring known as "Extract Class". Martin Fowler discusses this technique in Refactoring: Improving the Design of Existing Code, which is in my opinion, the finest discussion of refactoring I've come across.
Ok, let's use the example on an Employee class. At first glimpse we'd all agree that an employee has a FirstName and a LastName, perhaps a middle name, all of which could comprise a FullName. So a typical implementation would look something like this:
C#
| using System; namespace RefactorSamples { /// <summary> /// Summary description for Employee. /// public class Employee { private string firstName; private string lastName; public Employee() { // // TODO: Add constructor logic here // } public Employee(string first, string last) { this.FirstName = first; this.LastName = last; } public string FirstName { get{return firstName;} set{firstName = value;} } public string LastName { get{return lastName;} set{lastName = value;} } public string GetFullName { get{return this.FirstName + " " + this.LastName;} } } } |
| private void btnOldWay_Click(object sender, System.EventArgs e) { Employee emp = new Employee(); emp.FirstName = "William"; emp.LastName = "Ryan"; string fullName = emp.GetFullName(); } |
| using System; namespace RefactorSamples { /// <summary> /// Summary description for Name. /// public class Name { private string firstName; private string lastName; public Name() { // // TODO: Add constructor logic here // } public Name(string first, string last) { this.FirstName = first; this.LastName = last; } public string FirstName { get{return firstName;} set{firstName = value;} } public string LastName { get{return lastName;} set{lastName = value;} } public string FullName { get{return this.FirstName + " " + this.LastName;} } } } |
| using System; namespace RefactorSamples { /// <summary> /// Summary description for Employee. /// public class Employee { private Name empName; public Employee() { // // TODO: Add constructor logic here // } public Employee(string first, string last) { } public Name EmployeeName { get{return empName;} set{empName = value;} } } } |
| private void btnNewWay_Click(object sender, System.EventArgs e) { Employee emp = new Employee(); emp.EmployeeName.FirstName = "William"; emp.EmployeeName.LastName = "Ryan"; string fullName = emp.EmployeeName.FullName; } |