How do you write Object Oriented Code?

I have a confession to make. I put “C++” on my resume when I graduated from college, but I didn’t know how to write Object Oriented Code.

It’s not that I didn’t know what OO was about. I just didn’t know how to create it. I don’t think that I’m alone – my sense is that most developers have the same experience.

The problem is that I can’t know ahead of time what the correct object model is – I have to see the code to know what I need to change to get there. Before Refactoring, I knew that changing the code unnecessarily was a way to create bugs – it was just a risk.

The result is that I never got a chance to really explore what good OO looks like. Without real exposure to good OO, and without the practice of making good OO, my understanding was merely academic. That is, I knew what OO was, but I didn’t know how to make OO code.

For example, suppose I have a bit of C# code in a method that looks like this:

// …

string filePath = …

bool isUncPath = filePath.StartsWith (@”\\”);

// …

I realize that this bit stands out from the rest of the method, and makes sense for ExtractMethod.I end up with:

// …

string filePath = …

bool isUncPath = IsUncPath (filePath);

// …

 

 

static bool IsUncPath (string filePath)

{

return filePath.StartsWith (@”\\”);

}

Great, I’ve made my code a little bit clearer by naming the algorithm. I also create the opportunity to reduce duplication by calling this method instead of writing the StartsWith again.

But then I remember my OO Jedi master telling me there’s something bad about static methods. I hear him say “static methods are on the wrong class. Put them on the class they act on.” In this case, there’s only one parameter, and it’s a string. It doesn’t make sense to ask a string if it’s a UNC path. So I create a new class, and put it there:

class FilePath

{

       readonly string _path;

       public FilePath (string path) { this._path = path; }

       public bool IsUnc { get { return this._path.StartsWith (@”\\”); } }

}

 

// …

FilePath filePath = new FilePath (…);

bool isUncPath = filePath.IsUncPath;

//

This is a very important step. This new code is about classes (FilePath) instead of being about functions (IsUncPath(string) ).

As is often the case with Refactoring, after you complete one step, you will become aware of new opportunities. There’s a good chance that I wouldn’t have been able to recognize the need for the FilePath class before I started. The Extract Method showed me the path to a new class. Now I see more opportunities:

· ReplaceTempWithQuery – remove the local ‘isUncPath’ variable, and just use ‘filePath.IsUncPath’ instead.

· As needed, add more methods to the FilePath class.

 

So now there’s hope for me. I can write some code that works (meets requirements) and not stop to try to anticipate what the classes should be. Then I can apply refactorings to get to code that is clear and Object Oriented.