The dichotomy of writing and reading object-oriented code
Tags: refactoring, oop
Published: 2017-01-07 05:02:21

---
title: The dichotomy of writing and reading object-oriented code
published: true
description: 
cover_image: 
tags: refactoring, oop
---

I've spent most of my twenty year career writing object-oriented code. Even though I've been at it for so long, I still find myself stuck with a particular roundabout habit.

**I usually don't *start* writing code in an object-oriented way. Instead, I often refactor into object-orientedness as part of my editing process.**

Here's a very simple example. Suppose I have a class called `User`. It looks something like this:

```c#
public class User
{
    public readonly string FirstName;
    public readonly string LastName;

    public User(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
}
```

In some other place in my application, far from the `User` class definition, I have an instance of the `User` object and output some information. Perhaps, I want to return a statement exclaiming a user has finished a task. Here's what I'd write:

```c#
public string GetTaskResponse(User myUser)
{ 
   return myUser.FirstName + " " + myUser.LastName + " has completed the task!";
}
```

When I need to assemble some logic using the data within an object, I tend to assemble that logic at the location that currently *needs* the logic. For instance, if I'm working in a view class that displays a user's full name, I'll scribble out that bit of logic in the view class *first*. **I do the work in the place where the work needs to be done**. This approach feels most natural to me. But, it is also not a particularly object-oriented style of thinking.

After I've completed this phase, I then hunt for where I can break this logic apart. I investigate whether I've duplicated some logic that already exists in another method to keep my code DRY. I also figure out where I can extract logic and replace them with more expressive methods within the class I am working in.

Back to our example, I might extract the portion of the string that creates the user's full name into a new method, still living in the place where I'm doing the work:

```c#
public string GetTaskResponse(User myUser)
{ 
   string fullName = getFullName(myUser);
   return fullName + " has completed the task!";
}

private string getFullName(User myUser)
{
    return myUser.FirstName + " " + myUser.LastName;
}
```

Up until now, though, I've simply written and refactored out code in a procedural way. My next move parks this method into the object it rightfully belongs to. In this simple case, `getFullName()` has an obvious home. It feels more appropriate in the `User` class itself. And, because it need only inspect the elements it owns, I can turn this method into a readonly property. `FullName` is now just another property of a `User` instance:

```c#
public class User
{
    public readonly string FirstName;
    public readonly string LastName;

    public string FullName
    {
        get 
        {
            return FirstName + " " + LastName;
        }
    }

    public User(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
}
```

This also pretties up the original method I was working in as well:

```c#
public string GetTaskResponse(User myUser)
{ 
   return myUser.FullName + " has completed the task!";
}
```

For a simple example like this, I've gone through this mental dance enough times to skip right to the end result. But, as the logic around features gets increasingly entangled and complex, I go through this dance a lot more deliberately. The refactorings aren't so obvious. **For me, object-oriented code is the end result of a fair amount of contemplative code editing.**

The funny thing is, I read code in much the same way. Procedural code feels far more approachable to me at the outset. If I'm on the lookout for a specific piece of logic, I can probably hunt down its whereabouts by driving down a procedural codebase far more quickly than by hopping around an object-oriented one. 

If reading or writing object-oriented code feels strange to me, then why program this way at all? Because, to me, object-oriented design wins out in the long run. The merits of OOP pay off the longer an application lives and grows.

An object-oriented codebase paints a far more consumable mental model of the *entire application* than a procedural codebase. But, consuming the whole thing naturally takes time. The trade-off I make with OOP is the immediate understanding of one particular piece of the puzzle for a slower, more methodical understanding of the application as a whole.

Keeping a clean, expressive, and well-designed object-oriented codebase is hard work. It requires persistent re-evaluation and discipline. The leap of faith is that it is *in this re-evaluation* where you cement a far better understanding of what you are actually building.