codethinked (kōdthĭngked) adj. To be consumed by or obsessed with code.

Just Isolate It Already

Sometimes while I am writing code I like to pretend that every chunk of non-trivial code is my enemy. In order for me to be successful in my task, I must not get surrounded by too many of my enemies, or all will be lost. Okay, so I don't actually pretend that, but that would be pretty sweet, wouldn't it? Well, if by “sweet” I meant “nerdy”, then yes, it would be “sweet”. Anyways, I do however try to hide as much code as possible so that I can see the intent of my code, rather than the actual implementation details.

This is an approach which goes right along with the declarative programming fad the is currently going around, where we want to be able to write less ceremony and more substance.

For example, I don't want to have to filter and sort a list like this:

var result = new List<Person>();
foreach (Person person in people)
{
    if ((person.Age > 40 && person.Weight > 180) || 
    (person.Age > 20 && person.Weight > 200))
    {
        result.Add(person);
    }
}

result.Sort((p, q) => {
    int lastResult = p.LastName.CompareTo(q.LastName);
    if (lastResult != 0) 
        return lastResult;
    return p.FirstName.CompareTo(q.FirstName);
});

I just want to be able to tell the list to filter itself, and let the compiler sort the rest out:

var result =
    people.Where(p => p.Age > 40 && p.Weight > 180)
        .Union(people.Where(p => p.Age > 20 && p.Weight > 200))
        .OrderBy(p => p.LastName)
        .ThenBy(p => p.FirstName);

Works very well, but in reality, the compiler really isn't the one deciding what to do here. It just so happens that someone wrote a library to abstract away from me the ceremony of looping through the list and doing each and every comparison. So why wouldn't you want to write your own code that way? What do you think is easier to read, this:

Person[] people = PersonRepository.GetPeople().ToArray();
Person oldestPerson = people[0];
foreach (Person person in people)
{
    if (person.Age > oldestPerson.Age)
    {
        oldestPerson = person;
    }
}

Person heaviestPerson = people[0];
foreach (Person person in people)
{
    if (person.Weight > heaviestPerson.Weight)
    {
        heaviestPerson = person;
    }
}

if (oldestPerson == heaviestPerson)
{
    oldestPerson.CancelInsurance();
}

Or this?

Person[] people = PersonRepository.GetPeople().ToArray();
Person heaviestPerson = GetHeaviestPerson(people);
Person oldestPerson = GetOldestPerson(people);

if (oldestPerson == heaviestPerson)
{
    oldestPerson.CancelInsurance();
}

To me I think that the answer is pretty obvious. (And yes, I could have made it cleaner with Linq, but I’m trying to make a point!) Although I’m not sure I agree with the logic of the code. Seems pretty crappy. :-) Yet many developers don't do this. Instead, they optimize for themselves in the current point in time. As long as the complexity does not overwhelm their brain in the moment they are writing their code, they don't try to hide anything or take the time to abstract. The problem is that your brain at the moment of writing the code is primed, pumped, and immersed in the logic of your code. In other words, your brain one week from now will not be able to full grasp the logic of the code you are looking at until you have walked through it and immersed yourself in it. So we need to write code for your future self.

I know that some people will probably get upset about me telling developers to hide code, but I honestly think that very little bad could come out of following this device. I've had people in the past that have criticized my code because they had to step through so many methods in order to get to where they wanted to be, but I'm not sure why they couldn't have used the breakpoint or just read the code. I guess they are used to code being so complex that they can't just read through it. (That’s right…I rock hard! Ha.)

I think the problem of not being able to see "everything at once" is really only applicable in very simple situations. What the human brain has problems with is breaking a problem down into pieces, not in being able to see it. I can put a million things in front of you and your brain will be able to see each one, but will your brain be able to pick apart and understand each piece? Absolutely not. So come on, just abstract it already.

Comments

Rik Hemsley

Putting logic into separate methods isn't hiding code, it's normal coding practice. Isn't it?

Rik Hemsley

July 31. 2009 04:47

United Kingdom
Ryan Roberts

Extension methods are a pretty good way of exploiting linq method chaining while avoiding it ending up looking like the bastard son of a 2001 data access layer.

This is an attempt to make hairy reflection queries in metaprogramming a little more bearable.


           return typeof(TModel).GetInterfaceProperties()
                .Union(typeof(TModel).PropertiesDerivedFrom<IDto>())
                .Union(typeof(TModel).PropertiesParameterisedBy<IDto>())
               .Union(typeof(TModel).PropertiesWithAttribute<DontStoreAttribute>())
                .Union(typeof(TModel).PropertiesWithAttribute<OptionAttribute>())
            .Select(p => p.Name);


I'd kill for a library levelling this sort of stuff into a consistent set of extensions. Designing it would be damn hard though.

Ryan Roberts

July 31. 2009 05:21

United Kingdom
John Miller

@Rik:

You'd think this would be a simple practice that all devs followed, but that's not always the case.

I've actually worked with other devs that did backwards refactoring on code I wrote. Turning nice, simple short methods into long, hard to read code chunks because they liked seeing all the code in one place (obviously they didn't care that it was impossible to test either). Since they were the client, all I could do was try my best to explain why smaller methods are better. And at the end of the day, they were the ones who had to maintain the software.

John Miller

July 31. 2009 09:04

United States
Justin Etheredge

@John Thanks! I was getting ready to write a comment that would have looked exactly like yours. You would think that this would be common practice, but it really isn't in many systems that I have seen.

Justin Etheredge

July 31. 2009 09:10

United States
Ryan Roberts

Turning nice, simple short methods into long, hard to read code chunks because they liked seeing all the code in one place

I have seen this done at a few places, it's a pretty common thing to do when people live in the debugger and want to be able to easily check as much state as possible. Drives me up the wall, and out of the door.

Ryan Roberts

July 31. 2009 09:19

United Kingdom
t_moriarty

It is not so much 'hiding' the implementation or creating an abstraction.  It is more so organizing and explicitily stating what is happening.

t_moriarty

July 31. 2009 12:38

United States
pingback

Pingback from arjansworld.com

Arjan’s World    » LINKBLOG for August 1, 2009

arjansworld.com

August 1. 2009 17:10

trackback

Just Isolate It Already - Justin Etheredge - CodeThinked

Thank you for submitting this cool story - Trackback from DotNetShoutout

DotNetShoutout

August 1. 2009 18:55

pingback

Pingback from blog.cwa.me.uk

Reflective Perspective - Chris Alcock  » The Morning Brew #403

blog.cwa.me.uk

August 3. 2009 05:11

Jef Claes

Amen Smile

Jef Claes

August 3. 2009 05:59

Netherlands
trackback

Just Isolate It Already

You've been kicked (a good thing) - Trackback from DotNetKicks.com

DotNetKicks.com

August 21. 2009 18:54

trackback

Just Isolate It Already

DotNetBurner - burning hot .net content

DotNetBurner - Linq

September 12. 2009 17:56

Rik Hemsley

I keep getting spam from this post. Can you please fix the spam or remove me from the notify list?

Thanks,
Rik

Rik Hemsley

September 16. 2009 17:39

United Kingdom
trackback

2009... Oh How I Will Miss Thee. Kinda.

2009... Oh How I Will Miss Thee. Kinda.

CodeThinked

December 30. 2009 17:12

Add Comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading