Curly's Law: Do One Thing

It’s a wonderful rule, but one doesn’t always have the luxury of following it.

Consider a horribly complex legacy application without any regression test suite, where all the original developers have long gone, and documentation is outdated. The application is retired, put into “maintenance mode” they say. But, inevitably, a new bug is reported, and the customer is important enough to dust off the source code and provide them with a fix. What is Junior Developer to do?

Modifying the behavior of the existing application is dangerous because Junior doesn’t understand all the ramifications of what he is changing. So Junior hacks a solution on top of an already complex ball of spaghetti, making sure to alter the minimal amount of existing logic as possible. If this requires duplicating some code that already lies somewhere in the abyss, I argue that it is a necessary evil.

“It’s true that “Do One Thing” becomes larger and larger as you move up the chain, more nebulous, more difficult to define. The higher up you get (OS level?), the more the One Thing becomes a vision statement rather than a concrete definition you can point to. But I’d still say it’s true; I think we can somewhat reliably point to the “Do One Thing” of OS X, Windows Vista, Ubuntu.”

Or Plan9. They took “Do One Thing” to a whole new level. I once read that adding features to the Plan9 code-base actually made it shrink.

I wonder how that relates to the ‘defects in programming languages’ discussion?

Ridiculous.

Jeff, do you actually know what you’re doing?

Let’s take a look at this:

class Employee
{
public Money calculatePay()
public void save()
public String reportHours()
}

There’s nothing wrong with this. Absolutely nothing.

These are simply convenience methods. That’s it. Put your functionality somewhere else, if need be.

These methods are simply an application of the facade pattern.

Jeff, do you actually know what you’re doing?

For the umpteenth time, I do not always agree with everything I quote. I didn’t write the example; Uncle Bob did.

Jeff,

I’d be interested to hear your comments on Kim’s suggestions to use dependency injection to solve the issue adequately. Since it was a Java problem, Uncle Bob’s idea to use Ruby to solve it seems… out of place.

“Does that mean you have to not re-use i for loops? :)”

Clearly it means you should only code a for-loop once. I can only assume the prescribed code would look something like this:

public delegate void LoopProcessDelegate(int Ndx);

public void Loop(int startNdx, 
                 int endNdx, 
                 LoopProcessDelegate process)
{
    for (int i = startNdx; i  endNdx; i++)
    {
        process(i);
    }
}

public void TestLoop()
{
    Loop(0, 9, new LoopProcessDelegate(
        delegate(int ndx)
        {
            Console.WriteLine(
                string.Format("{0} : Hello World", ndx));  
        }));
}

Isn’t that much better?
-Andy

For the humor-impaired, yes, this is a joke.
Nice article Jeff…

Just gotta be careful when creating objects…

http://www.codinghorror.com/blog/archives/000801.html

So, finding the right place for things even happens in blog entries…

Both are EXCELLENT articles, and the point being made is quite well made. Thanks, Jeff!

“This class violates the SRP because it has three reasons to change:”

How can you possibly justify this statement without providing even a hint of implementation?

Each of these methods would be reasonable as long as they were implemented reasonably.

Jeff, do you actually know what you’re doing?

Of course not. If he knew what he was doing, he wouldn’t be writing a blog. He’d be leaving snarky comments on other people’s blogs.

How many ways?

Well, we started with OAOO, then DRY, then Single Point of Truth. Actually, Curly predates the DRY acronym.

Oh, wait… we started a long time before OAOO. We spoke in the negative about “multiple maintenance points” and before that…

We’ll find a dozen ways to say it, but the Java people will decide that they need one more so that they can maintain their terminology ghetto, and we’ll have at least a million and one.

Yeah, I’m mostly joking. The point is that we do keep restating the same thing for decades, and saying in more ways and more clever ways doesn’t seem to cause people to actually do it. The interesting question is how can we help people do it? Some of us are insane (in the Einstein-ian mode) and keep trying the same thing by stating it over and over. Other than following the principle ourselves and teaching it to others, what can we do?

I’ve been perusing your blog for about an hour and have found some useful stuff and some not-so-useful stuff. Your “Curly’s Law” post is extremely useful. Your “Branding” and “Office Tour” posting are not.

My friendly advice is to leave “branding” and “tours” to the marketing hacks and give us some more coding pointers.

Good article. Nothing I didn’t know before, but as I was reading through it I immediately thought about a current program I’m writing that I got sloppy on and just copy-pasted a loop (with minor modifications) rather than turning it into a proper function. Lo and behold, I go back and look at the code after two weeks and another guy has come through and fixed a bug in one of the loops but not the other (guess he just missed it). So I converted it into a proper function.

And all before finishing reading the blog post.

In the '70’s, I knew Black Curley in Austin. He owned a ‘junk yard’ where I scrounged VW parts.

Curley’s Rule was "You gots to keep fixin’ it 'tils you gets it fixed."
And the corallary: “If it woiks, it’s fixed.”

He could have been a programmer… .

Click my name for a different take on the whole Curly’s Law thang …

Hey Now Jeff,

Some of these oldder posts are still so good.

Coding Horror fan,
Catto

The only problem with the proposed solution is that partial classes didn’t show up until .Net 2.0, so if you’re working in an older version of the runtime (because, say, you’re working with a web app built in ASP.Net 1.1 and, say, upgrading it is a nightmare) you either stick all the methods in one class or you get gnarly with your class structure to compartmentalize it.
As far as editing the data and reporting layers of Employee separate from Employee’s business logic, it depends. Is the data layer considered to be the database and the stored procedures you use to have your code talk to it or is it code to talk to the database? If it’s code to talk to the database, why separate it from the Employee class? That sort of monotonic relationship doesn’t earn you anything: the Employee class is worthless without its data layer and the data interface layer is worthless without the Employee class, so have Employee encapsulate the data interface layer.
Even with the GoF’s patternalia on speed-dial, it’s easy to mangle the implementation of something like MVC - lord knows I’ve done it enough in my time.

There is nothing wrong with the employee class. Don’t listen to this example or else you could end with a system with object bloat.

DRY works here if calculatepay only exists in the employee class and not in the front end, in the RDMS layer, or is repeated in another class.

Employee could be a base class with calculatepay being an overridable method. Other class inherit and may calculate pay differently by implementing there own version of calculatepay, or they use base employee method.

You can have an object that has multiple methods that update that objects state. Its a guideline not an absolute rule. If you folow this rule to the letter, you will have lots of little classes in your application and your code will be hard to follow.

I don’t agree with the Single Responsibility Principle but that’s just my opinion. I agree that all business logic for employee’s should be located in one location of code and not spread throughout the codebase.

If you go back into histroy and re-read the literature regarding Coupling and Cohesion (or even normalisation and denormalisation) you are half way there. Look cross cutting concerns as well as covered AOP.

All of this has been known and covered for decades.

Some of these older posts are still so good!

Do one thing = Kanban!

PS. Kanban = T-Card system, used around the world for decades. (see https://web.archive.org/web/20110716181719/http://t-cardsystems.com/index.html).

1 Like