The Primary Value of Software

I chose… poorly.

My team has been pulling out stops all winter long to build a cutting edge single-page app for a very important client. Suddenly, earlier this month, the SPA framework I picked officially white-flagged it.

poorly

Yet, in spite of this and plenty of coffee, I sleep like a baby.

But isn’t this the nightmare scenario that our parents and managers warned us about when we started using open-source libraries? What if the sole proprietor of the project gets hit by a bus? What if the poor schlub making this thing for free wakes up and gets a real job? What if? They’re all going to laugh at you.

Oh, logic from 2007. Adorbs.

Of course I care about the app, and the long-term implications of the tools we choose for it. But I’m not uptight about having chosen the “wrong” SPA framework for our client because my team and I are clear on what really makes software valuable. And we work hard to ensure that our app has it.

What makes software valuable?

This is an idea that I picked up from “Uncle” Bob Martin’s phenomenal Clean Code series. It has changed the way I view my work, and I hope it does the same for you.

Ask just about anyone in our industry what gives software its value, and they’ll tell you its all about solving problems for users. And they would be right–solving problems makes the software valuable, and most folks who pay for software likely believe that this is the extent of what they are paying for.

But solving a problem that the user has today is the secondary value of software.

epiphany

The primary value of software is that it is soft. That it is resilient in the face of inevitable change. That it not only meets the users’ requirements and solves their problems in the present tense, but that it can be readily adapted to meet needs that will arrive tomorrow, or the next day.

But this doesn’t just happen.

So, this is amazing news, right? Our software has a value we didn’t even know was there–let’s charge more for it!

Not so fast, there, Steve. This primary value thing is what makes software the bee’s knees, but it doesn’t occur naturally just because you’re writing some code. Most systems do not possess this quality.

What does it take, then? Planning for every possible permutation of our application’s future? Clairvoyance sufficient to pick the winning stack? Infinitely configurable options?

No, thank Turing. In order to unlock the primary value of software, the code from which it is built must be clean.

He’s doing it again

Man, I sure keep playing that clean code fiddle, don’t I?

And with good reason. It’s not because I am selfishly obsessed with the placement of brackets, spaces v. tabs, or the intricate contours of my navel, however engrossing each of those subjects may be. It’s not about preaching some esoteric set of nerd rules. It’s about long-term vs. short-term thinking.

Software Craftsmanship is ultimately about the value of software. Only clean code, code that respects the SOLID principles, code that is covered by tests in the way that only test-driven code can be, can stand up to change over time and truly yield this value. Whether that change comes from a shift in the nature of the users’ problem set or in the fickle wind that blows a new de facto standard library across our desks.

No warm milk for me, thanks

So we code clean and keep it clean. Our framework-y plumbing code depends on our valued domain logic, rather than our domain logic residing within framework-dependent code. And every new feature begins with a design conversation and one failing test at a time.

Between that and Good-Guy Eisenberg‘s generous plans for Durandal that make it more of a finished project than an abandoned one, my team is looking at a pretty nice-to-have problem in Angular taking the title.

firstworldproblemsgirl

So yeah, I’m getting my eight hours. Are you?

The End of “Test-Driven” Development

In the not-too-distant future, we are going to finally stop hearing about Test-Driven Development. And by this, of course, I mean that the “Test-Driven” part of Development will just be assumed, because everybody will be writing code that way. In the meantime, you and your team can either be ahead of the curve or not.

Here’s why I’m so sure.

TDD takes less time.

You heard me. Less. But how could this be? Writing unit tests every time we write code basically means we have to produce twice as much code, right?

Yes, tests are additional code that must be written, usually in a one-to-one ratio with the production code. But to argue that twice the lines of code takes twice the time to produce is short-sighted–it only makes sense if you see your development team as the typing pool.

We do not type for a living. We define patterns in logic and data, and wire them together to build tools that people can use. And the fewer lines of code we use to do this, the better we are at our job. You don’t measure productivity by lines of code, do you? Then why would you estimate development work using the same broken thinking?

The measurable output of software development is functionality. Features. And features get done (and stay done) faster when we have confidence that the components involved are chewing gum and kicking butt. The test-first approach gives us this confidence.

It also, incidentally, yields less production code per feature. If you’re into that sort of thing. More on that in a second.

TDD keeps developers focused.

Do you want to talk productivity? Let’s talk productivity.

Every person who has ever gotten things done ever has had one essential tool in common: a to-do list. When we write tasks down, we are extracting them from the soggy, unreliable twerkfest in our head, and transforming them into an unflinching list of verbs. Only then can we stop treading water in an ocean of distractions and make a beeline for our next action.

If you have done TDD enough to warrant having an opinion on it at all, you know that writing a unit test before you’ve written the production code that makes it pass is exactly like writing something down on a to-do list and then doing it. Defining the next action in this way keeps us on task in the face of the deeply complex series of steps it often takes to implement a software feature.

Remember when I said that using TDD leads to less production code? This is due to the focusing effect that writing a test, and then making that test pass, has. We’re just oscillating between the red and green–there’s no step for gold-plated YAGNI in that workflow. Defining a new test every few minutes gets us in the habit of questioning, frequently, whether what we’re coding is actually called for by the feature.

TDD more than pays for itself.

The time required for functionally comparable development tasks is not linear over the life of a project. A rigor mortis sets in as the codebase grows, because every decision made by every nerd on every line of code narrows the number of choices that the next nerd can make. But if our code is protected from regression and organized well (say, by being wrapped in a cozy, cozy blanket of unit tests woven during development), this harsh curve flattens out.

Initially, while we are still learning and forming the TDD habit, development time may increase on the order of ten to twenty percent. Do not panic. This is usually where the developer (or manager of the micro- variety) gets nervous and start skipping the test-first thing, thinking that this will speed things along. We settle back into our old habits, entropy sets in, and any benefit that could have been had from TDD is lost.

But if we hang on tight through this dip and let the habit take hold, our estimates swing back to their normal size, and we notice that the only thing inflating them in the first place was a learning curve.

By keeping the code focused, protected, and consistent, TDD can drastically cut development, testing, and debugging time over the lifespan of an application. It is fragile and unmaintainable code, undetected bugs, and unforeseen design issues that cause a project to miss deadlines and blow budgets; not an up-front investment in quality and morale.

“TDD” will just become “D”.

tenaciousd-1349977935

[via]

When you get your head around the discipline of TDD, and the return on investment to be had from rocking it, it becomes difficult to see a future in which nerds and non-nerds alike don’t get behind it. Until then, teams of sad coders everywhere will keep chasing the short-term gains of Debug-Later Programming, emitting reams of sad, unsustainable code, and generally doing things that sad people do.

I mean, probably.

How Behavior-Driven Development Saved My Code from the Jedi Interruption

So, I’m not the sharpest sandwich in the drawer. This was demonstrated to me again in no uncertain terms just the other day, as I was working up some routing logic for a new Durandal-based app. The JavaScript in question went something like this.

router.guardRoute = function (instance, instruction) {
    var routeInfo = instruction.config;
    if (!_isAuthenticated && !routeInfo.settings.anonymous)
        return getAuthenticationUrl();
 
    return true;
};

It’s not an original story. guardRoute runs every time the user tries to navigate to a view in the app. This snippet simply ensures that unauthenticated users get redirected to a login page if the new route is not available to anonymous visitors. And it hummed along happily for a short while.

When Suddenly

Apparently, if the optional settings property is not present on routeInfo, an exception gets thrown, all of the air leaks out of our app, and the rotation of the Earth sort of grinds to a halt. Could be a bug.

No worries, thought I. We just needed to test route.settings before testing route.settings.anonymous.

if (!isAuthenticated && !route.settings && !route.settings.anonymous)

Hmm. That wasn’t quite right–what if we grouped those second two conditions together?

if (!isAuthenticated && !(route.settings && route.settings.anonymous))

That felt correct. But static analysis alone wasn’t enough to give me a warm fuzzy that my code was up to its arguably very important job.

Like I said, I’m not the brightest knife at the gun fight. I was standing on my head and counting on my fingers to ensure that this code was going to work. Maybe if this was the only thing I had going on at the time, perhaps if I was able to hone a laser-like beam of attention on the problem, I could have gotten to the point where I was confident in its correctness.

But, as it happened, at that moment my tête-à-tête with reinventing the authentication routing wheel took a back seat to making a peanut butter sandwich for this guy.

jacob

To clarify, I was working from home that day. I mean, I wouldn’t want you thinking that Aptera keeps the kind of office where tiny hungry children just sort of wander around in Jedi cosplay and dislodge people from their respective trains of thought.

Anyway. By this point I was spreading peanut butter on bread and spiraling hard into a full-on Hanselman phony complex on account of this gear just not catching in my head. What was wrong with me?

Enter BDD

As is often the case, the solution was there before the problem. I just needed to take a few minutes to wire up some Jasmine specs.

Who?

Let me back up. By now, you probably have heard all about the wonders of Test Driven Development (TDD). How it will make your code flawless, fix your marriage, and scratch that itch in the middle of your back that you can never quite get to. But you may not be familiar with TDD’s more stylish younger brother, BDD. That’d be Behavior Driven Development, if you’re not into the whole brevity thing.

The thing about traditional TDD is that it has a pretty fundamental flaw–it is backward. Backward, at least, in terms of its underlying metaphor of testing a thing. See, in meatspace, in order to run a test on something (like in a laboratory), it first needs to exist. So when we’re told to write a test for code that doesn’t yet exist, we buck; how can we write a test when we don’t even know what our code looks like yet? If TDD is something you’ve been meaning to get into, but you could never quite find the front door on it, this is probably why.

The behavior-driven approach resolves this cognitive dissonance, not by being mechanically any different at all from TDD, but by flipping the assumption that what we are writing first is a test. What we write first, says BDD, is a spec–a specification that defines exactly what the code under test will do. With this, our brains crack into applause–we write code from specifications all the time.

In execution, though, a spec is just a unit test that’s named well. Here’s how a typical test suite (using QUnit here) might come off in the naming department.

module("PB and J tests");
 
test("bread test", function(){     
    // assert stuff about the bread
});
 
test("peanut butter test", function(){     
    // assert stuff about the peanut butter
});
 
test("jelly test", function(){     
    // assert stuff about the jelly
});
 
// etc.

Make a barf noise here, amirite? Here’s how we’d name things using the aforementioned Jasmine, a BDD framework for testing JavaScript code.

describe("A peanut butter sandwich", function() {
    
    it("has two slices of bread", function () {          
        // assert stuff about the bread     
    });         
    
    it("has peanut butter on one slice", function () {        
        // assert stuff about the peanut butter    
    });
        
    it("has jelly on one slice", function () {          
        // assert stuff about the jelly    
    });

    // etc.
});

What we expect to have happen in our code is just so much clearer when we spell it out in English1. My very favorite thing about wording each spec like this is that Jasmine fuses the title from describe() with the phrase from each it() as subject and predicate. The output shown in the test runner then becomes a series of transitive statements about the code under test.

  • A peanut butter sandwich has two slices of bread.
  • A peanut butter sandwich has peanut butter on one slice.
  • A peanut butter sandwich has jelly on one slice.

And, of course, each of these comes with a red or green mark that shows us whether it is true yet.

The value of a good suite of BDD specs is that it is a direct English translation between our expectations for the code that we haven’t written yet, and the code that will test it to ensure that it meets the specification. The spec says what our code does. Our code does what the spec says. When we’ve made it all turn green, it works.

And here’s the part where I actually solved my problem

So cut back to the other day, post-peanut-butter-and-jelly-hiatus. I stopped banging my head directly against my troublesome code, opting instead to simply define, in plain English, what I wanted it to do.

describe("The auth service", function () {
});

A rousing start. Yessir, the auth service is in fact what I would like to be describing today.

describe("The auth service", function () {
 
    it("indicates when the user is authenticated", function () {
        var a = new auth(mocks.api);
        spyOn(mocks.api.login, 'GET').andReturn('jfazzaro@apterainc.com');
        a.start();
        expect(a.isAuthenticated()).toBe(true);
    });
 
    it("indicates when the user is not authenticated", function () {
        var a = new auth(mocks.api);
        spyOn(mocks.api.login, 'GET').andReturn(undefined);
        a.start();
        expect(a.isAuthenticated()).toBe(false);
    });
 
    var undefined;
    var mocks = {
        api: {
            login: {
                GET: function () { }
            }
        }
    };
});

In the first two specs above, I defined clearly what the isAuthenticated() method does, and since this was already implemented, they passed. But the real turning point was when it was time to spec out the service’s ability to determine whether a route was anonymous. I wrote the next two specifications as implementation-agnostic descriptions of what I was actually after.

it("indicates when a route is anonymous", function () {
});
 
it("indicates when a route is not anonymous", function () {
});

Once that was outside of my head and staring back at me in plain text, it occurred to me that that if block from the opening of this post–

if (!isAuthenticated && !(route.settings && route.settings.anonymous))

–yes, that one, was just trying too hard. The last two-thirds of it were an attempt to solve the anonymous route problem I had just finished specifying. And the fact that they weren’t isolated in their own named and testable function was what made it so difficult for me to quickly ascertain my code’s validity.

I descended on the keys with fresh purpose, spelling out the anonymous route checking functionality, as it should look like from the outside.

it("indicates when a route is anonymous", function () {
    var a = new auth(mocks.api);
    expect(a.isAnonymous(mocks.routes.signin)).toBe(true);
});
 
it("indicates when a route is not anonymous", function () {
    var a = new auth(mocks.api);
    expect(a.isAnonymous(mocks.routes.dashboard)).toBe(false);
    expect(a.isAnonymous(mocks.routes.simple)).toBe(false);
});
 
var mocks = {
    api: {
        login: {
            GET: function () { }
        }
    }, routes: {
        signin: { route: 'signin', moduleId: 'viewmodels/signin', settings: { anonymous: true } },
        dashboard: { route: '', moduleId: 'viewmodels/dashboard', settings: { anonymous: false } },
        simple: { route: 'simple/route', moduleId: 'viewmodels/simple/route' }
    }
};

Naturally, these tests went red in my test runner, because the isAnonymous(route) function didn’t exist yet. But it soon did.

function isAnonymous(route) {
    return route.settings && route.settings.anonymous;
}

Then, the tests went–red. Wait, still red? Yep.

auth-spec-fail

I was close, but I may never have picked out the distinction between undefined and false without that spec in place to guide me. I updated the function, making it a bit more specific in the truthy/falsy department.

function isAnonymous(route) {
    return (route.settings != undefined && route.settings.anonymous);
}

Boom. Greensville.

Finally, now that this irritating fruit fly of logic was labeled and tested, that code in guardRoute could now be read more organically, too.

if (!isAuthenticated && !isAnonymous(route))

When I read it aloud again in almost-English, I picked out a further subtlety: I really should test the route for non-anonymity first. I mean, if we’re hitting an anonymous route, our authentication status really doesn’t matter, and we shouldn’t waste any cycles checking on it.

if (!isAnonymous(route) && !isAuthenticated)

I like to imagine that Sam Clemens himself wouldn’t have put it more succinctly.

We think in English. The terse syntax of our favorite programming language becomes more compatible with the way we actually think when we use our words to specify and test our code. And offloading these micro-requirements from our heads into a self-testing suite of specifications doesn’t just make our software more readable and reliable, it also frees us up to focus on more important things.

Playing Jedi with the little guy, for instance.


  1. It’s a fair assumption that if you’re reading this in English, you’re thinking in English. If that’s not the case, by all means mentally drop your preference in whenever I mention it. Unless your preference is Klingon, in which case you must stop reading altogether and figure out where things went wrong for you.

Extension Cords, Tea Kettle Whistling, and the Contractor’s Wrap for Your Code

A few weekends ago, I found myself standing in my garage, regretting my ambitions of yard work and struggling to unwind the pile of orange spaghetti that was, at one point, a tidily wrapped fifty-foot extension cord.

Then I took a deep breath and reminded myself that things were going to be different this time.

See, the blog Art of Manliness had just run a post on how to wrap your extension cords like a contractor, using a technique that enables you to quickly uncoil whatever length of cord you need, without it ever becoming a tangled mess. The post was mostly pictures, so I managed to get through it. And things did, in fact, turn out differently this time.

cord
[via]

Well. The orange garage-spaghetti department of things, at least.

Cool Story, Bro

So what, you may well ask, does my high-voltage gardening adventure have to do with building software?

Here’s the thing about code: it gets inscrutably balled up just like this all the time. And while I’m sure that you, dear reader, have never yourself been responsible for such a mess, I have borne witness as this recurring nightmare slowly unfolded on many an unsuspecting software venture.

In the beginning of the project, there’s the familiar big talk about how This Time, we’re going to keep things organized. This Time, we’re going to write REUSABLE code. This Time, we’re going to work harder and do it right. Things are going to be different This Time.

reusable

So, development hops along at a decent pace at first–like winding the first few coils in that orange extension cord. But soon, it gets harder and harder to actually reuse the REUSABLE components. Changes take longer to implement, you swear that you can hear the faint whistle of a tea kettle that is perpetually beginning to boil, and your source has seemingly contorted itself into shapes that would make a sailor cry. And when the new devs (that management has hurled at the problem) climb aboard and try to unravel a piece of the code for what they’re working on, those kinks just get twisted tighter. Soon, everyone involved sinks into their chair with the same question burning in their brain.

How did this happen to our code again?

We get it, Fazzaro. Code bad, team sad. But what exactly can a young person like myself do to invoke the beneficence of the programming gods that they may no longer smite us in this way?

Glad you asked. Let’s get specific.

In my travels, the most common cause of egregious code fluster in the modern business app is a poorly scoped Entity Framework DbContext1. What might one of those look like? Stop me if you’ve heard this one: I’ve updated these entities, added two new ones over here, deleted that ugly one, and our REUSABLE code just called SaveChanges three times in the course of doing its business. So, I’m going to jiggle the handle and call it one more time over here for this case. You know, just to be sure.

Sure, the EF implements the Unit of Work and Repository patterns right out of the box. But this only helps if we’re using them correctly–which really comes down to understanding where the context belongs. Should a new context be created to persist each change to an entity? Should we create a new one for every method that alters data? Or should we just keep a global singleton context instance, and call SaveChanges on it when it feels right?

That’d be no, no, and hand over your keys, dude, respectively. Paths to the spaghetti side, those are. Instead, to keep the unit of work thing straight, I just keep two simple rules in mind:

  1. The unit of work does not go inside the reusable code, the reusable code goes inside of the unit of work.
  2. As soon as you create a new context or call SaveChanges, you are no longer writing the reusable code.

Some of your code will never be reusable, and that’s okay; that’s where the context goes. As for the rest of your code, here’s a way to make it truly and sustainably reusable.

I’m going to illustrate this by generally being abusive to a particularly troubling snippet of sample code from the Wingtip Toys tutorial on MSDN. In the the application that the tutorial guides you through building, the ShoppingCartActions class houses the domain logic around adding, updating, and removing items from a shopping cart. I’ve abbreviated the class here to just show the salient bits:

public class ShoppingCartActions {
    public string ShoppingCartId { get; set; }

    private ProductContext _db = new ProductContext();
 
    public const string CartSessionKey = "CartId";

    public void AddToCart(int id) {
        // Retrieve the product from the database. 
        ShoppingCartId = GetCartId();

        var cartItem = _db.ShoppingCartItems.SingleOrDefault(
            c => c.CartId == ShoppingCartId
            && c.ProductId == id);
        if (cartItem == null) {
        // Create a new cart item if no cart item exists. 
            cartItem = new CartItem {
                ItemId = Guid.NewGuid().ToString(),
                ProductId = id,
                CartId = ShoppingCartId,
                Product = _db.Products.SingleOrDefault(
                    p => p.ProductID == id),
                Quantity = 1,
                DateCreated = DateTime.Now
            };

            _db.ShoppingCartItems.Add(cartItem);
        } else {
            // If the item does exist in the cart, 
            // then add one to the quantity. 
            cartItem.Quantity++;
        }
        _db.SaveChanges();
    }

    public void UpdateShoppingCartDatabase(String cartId, ShoppingCartUpdates[] CartItemUpdates) {
        using (var db = new ProductContext()) {
            int CartItemCount = CartItemUpdates.Count();
            List<CartItem> myCart = GetCartItems();
            foreach (var cartItem in myCart) {
                // Iterate through all rows within shopping cart list 
                for (int i = 0; i < CartItemCount; i++) {
                    if (cartItem.Product.ProductID == CartItemUpdates[i].ProductId) {
                        if (CartItemUpdates[i].PurchaseQuantity < 1 || CartItemUpdates[i].RemoveItem == true) {
                            RemoveItem(cartId, cartItem.ProductId);
                        } else {
                            UpdateItem(cartId, cartItem.ProductId, CartItemUpdates[i].PurchaseQuantity);
                        }
                    }
                }
            }
        }
    }

    public void RemoveItem(string removeCartID, int removeProductID) {
        using (var db = new ProductContext()) {
            var myItem = (from c in db.ShoppingCartItems where c.CartId == removeCartID && c.Product.ProductID == removeProductID select c).FirstOrDefault();
            if (myItem != null) {
                db.ShoppingCartItems.Remove(myItem);
                db.SaveChanges();
            }
        }
    }

    public void UpdateItem(string updateCartID, int updateProductID, int quantity) {
        using (var db = new ProductContext()) {
            var myItem = (from c in db.ShoppingCartItems where c.CartId == updateCartID && c.Product.ProductID == updateProductID select c).FirstOrDefault();
            if (myItem != null) {
                myItem.Quantity = quantity;
                db.SaveChanges();
            }
        }
    }
}

And here are a few lines from a nearby code-behind class that consumes ShoppingCartActions:

ShoppingCartActions usersShoppingCart = new ShoppingCartActions();
usersShoppingCart.AddToCart(Convert.ToInt16(rawId));

Oh, it looks innocent enough, all right. Until you notice that not only does each instance of ShoppingCartActions get its very own private ProductContext, but that when it’s time to call RemoveItem, UpdateItem, or (Robert Cecil Martin help you) UpdateShoppingCartDatabase, we’re whipping off new context instances like they are going out of style. Gross.

Why is that gross? Well, suppose that we had another page in our application that needed to perform similar actions on a shopping cart, in a slightly alternate combination:

ShoppingCartActions usersShoppingCart = new ShoppingCartActions();
usersShoppingCart.AddToCart(Convert.ToInt16(rawId1));
usersShoppingCart.AddToCart(Convert.ToInt16(rawId2));

var changes = GetShoppingCartChanges();
usersShoppingCart.UpdateShoppingCartDatabase(cartId, changes);

I count no fewer than four new ProductContext instances created here–and easily many more, depending on how many changes were in that list we passed in to UpdateShoppingCartDatabase. And if we needed this particular set of operations to be transactional, so that if one failed, no changes were sent to the database at all? Forget it. Yes, gross.

And yet, with a simple, subtle refactoring, we can turn this heinous double sheetbend into a nimble little slipknot. All we have to do is get it to let go of control of the context:

public class ShoppingCartActions {
    public string ShoppingCartId { get; set; }

    private ProductContext _db;

    public ShoppingCartActions(ProductContext db) {
        _db = db;
    }

    public void AddToCart(int id) {
        // Retrieve the product from the database. 
        ShoppingCartId = GetCartId();

        var cartItem = _db.ShoppingCartItems.SingleOrDefault(
            c => c.CartId == ShoppingCartId
            && c.ProductId == id);
        if (cartItem == null) {
            // Create a new cart item if no cart item exists. 
            cartItem = new CartItem {
                ItemId = Guid.NewGuid().ToString(),
                ProductId = id,
                CartId = ShoppingCartId,
                Product = _db.Products.SingleOrDefault(
                p => p.ProductID == id),
                Quantity = 1,
                DateCreated = DateTime.Now
            };

            _db.ShoppingCartItems.Add(cartItem);
        } else {
            // If the item does exist in the cart, 
            // then add one to the quantity. 
            cartItem.Quantity++;
        }
    }

    public void UpdateShoppingCartDatabase(String cartId, ShoppingCartUpdates[] CartItemUpdates) {
        int CartItemCount = CartItemUpdates.Count();
        List<CartItem> myCart = GetCartItems();
        foreach (var cartItem in myCart) {
            // Iterate through all rows within shopping cart list 
            for (int i = 0; i < CartItemCount; i++) {
                if (cartItem.Product.ProductID == CartItemUpdates[i].ProductId) {
                    if (CartItemUpdates[i].PurchaseQuantity < 1 || CartItemUpdates[i].RemoveItem == true) {
                        RemoveItem(cartId, cartItem.ProductId);
                    } else {
                        UpdateItem(cartId, cartItem.ProductId, CartItemUpdates[i].PurchaseQuantity);
                    }
                }
            }
        }
    }

    public void RemoveItem(string removeCartID, int removeProductID) {
        var myItem = (from c in _db.ShoppingCartItems
            where c.CartId == removeCartID && c.Product.ProductID == removeProductID
            select c).FirstOrDefault();
        if (myItem != null)
            _db.ShoppingCartItems.Remove(myItem);
    }

    public void UpdateItem(string updateCartID, int updateProductID, int quantity) {
        var myItem = (from c in _db.ShoppingCartItems
            where c.CartId == updateCartID && c.Product.ProductID == updateProductID
            select c).FirstOrDefault();
        if (myItem != null)
            myItem.Quantity = quantity;
    }
}

You almost can’t see the difference–but note the complete lack of context instantiation, and that nowhere in there do we even consider calling SaveChanges. This is our rule number two in action; ShoppingCartActions just isn’t in the business of owning the ProductContext anymore.

Here’s how we can leverage this class in our code-behind now:

using (var db = new ProductContext()) {

    ShoppingCartActions usersShoppingCart = new ShoppingCartActions(db);
    usersShoppingCart.AddToCart(Convert.ToInt16(rawId1));
    usersShoppingCart.AddToCart(Convert.ToInt16(rawId2));
    var changes = GetShoppingCartChanges();
    usersShoppingCart.UpdateShoppingCartDatabase(cartId, changes);

    db.SaveChanges(); 
}

And that illustrates rule number one. We instantiate one ProductContext, we do our business with it, and we send a single set of changes to the database. Not only can the new ShoppingCartActions be applied to many different situations throughout the app, but it will scale like a mother to boot.

Dependency Injection is the Contractor’s Wrap for Code

By now, the sharper nerds in my readership will be calling out that I have simply invoked the Dependency Injection technique here, and they would be correct. We took a component that the logic was dependent upon and made sure that it came from somewhere else, outside of the logic’s implementation. Dependencies like context instances are really just input for the logic to use in its calculations. What’s really going to knock your socks off later on is that this pattern of threading dependencies through class constructors applies to any number of types that have nothing at all to do with the Entity Framework, or even data storage, for that matter. HttpContext, FileStream, SPWeb, RouteCollection, you name it. They are all just input for our code to operate upon.

With just a minor tweak to the way we weave our classes together, our source can become tangle-free and flexible, and the next developer to lay hands on our app doesn’t have to worry about it curling up into an untenable heap of sad. It’s a shot in the arm for the sustainability and success of the app, and for the happiness of the team. And things are totally going to be different this time.

Well. The weeping-sailor heinous-code-fluster department of things, at least.


  1. Okay, so maybe you’re not using the Entity Framework (or its newer DbContext API), but don’t check out on me just yet–you might well be rocking a similarly steaming pile with some other ORM/unit-of-work-type implementation. Keep playing along at home, mentally adjusting my terminology to whatever busted situation you’re holding onto over there. I’ll make it worth your while.

Kent Beck’s Mother Doesn’t Work Here, and Neither Does Yours

popmechanics1950

Way back in 1997, when it was still just fine for a dude to rock a shiny bowling shirt and bleach the crest of his bangs, Kent Beck identified a three-step process for writing great code. Likely a truer and more useful thing to perhaps have tattooed on one’s self than ninety percent of the other ink permanently installed during the Clinton administration, it went a little something like this:

  1. Make it work
  2. Make it right
  3. Make it fast

Sakes, does that ever roll off the tongue and come off punchy in a meeting. But, just so we’re all running our reader finger along the same page with regard to what each of those amount to:

  • Make it work means that the tests pass and the software functions as advertised.
  • Make it right means that the code has been refactored into something that you love so much that you wish there was a Clean Code Magazine and that they could come and interview you about it. You know. DRY, SOLID, readable and maintainable.
  • Make it fast means that the code is tuned for performance.

“Yeah, Jon, so, yeah. That’s fine for him and his pals in their Ivory Tower where they pair and write interfaces and invert dependencies and eat ice cream all day not that I’m angry. But our boss won’t let us do steps two and three. What does Kent Beck say about that?”

Well, I can’t speak for Beck. But I’d say we just found out why your code sucks.

Also: it is totally your fault.

Here’s why.

It’s easy to assume that these steps are supposed to happen at the lifecycle scope of a system, like phases in a project. As in:

  1. First, we spend six months getting the application to work.
  2. Then we go through the code with a slide rule, put some fresh tape on its glasses, and inflict a neckbeard wish-list that results in absolutely zero changes apparent to the user. If we’ve done it right.
  3. Finally, we go on stopwatch safari, hunting down for-each loops and parallelifying them. Also? Indexes.

And at long last the user has the very same feature (and bug) set that they’ve had for a year, except now all the nerds are happy and the budget is blown. Fowler be praised.

I suppose it’s possible to sell this approach to the patron of your sundry bracketed text files and persuade them to loosen their purse strings for months on end with nothing to show for it but QUALITY CODE. But it’s not likely. Nor should we expect anything of the sort—in fact, it’s bad business, and if you’re working for someone who is kosher with that schedule, they are a fool with whom said purse will soon be parted.

Don’t ask, don’t tell, and the hidden fourth step

In any case, from the non-nerd perspective, there is exactly one step to writing great code:

  1. Make it work

Make it right and Make it fast have nothing to do with anyone who isn’t slinging code. Heed another Clinton-era gem here: don’t ask, don’t tell. Trust me, you’re not Daniel Day-Lewis, and the users don’t care about your process. Steps two and three are assumed, rolled up into step one–of course it’s going to be right and fast.

And this leads us directly to how we can implement Beck’s method in the real world.

See, there’s a hidden fourth step that will help us remember where the first three belong. That fourth step? Check in the code.

That’s right. The three “Make it“s are not great hairy brushes with which to paint the entire codebase, one after the other. Rather, they represent an iterative approach to crafting each individual feature, before we can declare it done. So really, it’s:

  1. Make the feature work
  2. Make the feature right
  3. Make the feature fast
  4. Commit the code

Oh, and

  1. Tell the boss that you made the feature work

Our mother doesn’t work here, you guys. But if we make tidying up after our own sloppy click handlers a part of what we do every day, we can have our cake and refactor it too.

 

 

Mmm. Refactored cake.

Naming Is A Developer Skill

So, you’re wired in. Code is darting from your synapses through the ends of your fingertips, sprawling gracefully onto the devenv-framed canvas. You know precisely how this little soft machine must do its dance, and the IntelliSense can barely keep up with the science dropping from behind your eyeballs.

Hold on—those calls there should be a separate class altogether. Right-click. Add. New.

Um.

Seriously. What should you call it?

hello

 

Who Cares

Naming is important. Naming is difficult. Naming is an under-taught and underrated developer skill.

In fact, I’m going to go as far as to say that if you’ve never been properly bound up on the New dialog, in a fix not unlike like the one I describe above, you don’t care enough about giving things good names in your code. And odds are that you have left a trail of miserable developers in your wake, weeping like lost children and wondering which end is up in that fragile pile of Visual Basic they just inherited from you.

I’m just guessing about the Visual Basic.

Assert.IsTrue(Coding == Writing);

If you are a developer, you are a writer. Like it or not. A good writer first considers their audience, then tunes in the best voice in which to address that audience. This principle holds as solidly for the halting cadence of a 4GL in a line-of-business app as it does for the email cast in the King’s English that you just sent to your boss.

Who, then, is our audience when we’re earbudded and thusly nerding at velocity? The computer, you may answer, with a jerk of the knee. If you’re a bit more clear-headed, the compiler. Both true, of course. But the oft-overlooked audience is every other dev on the planet who will ever touch this code ever. You are carbon copying them on what you are telling the machine to do, and your voice to them should be just as unmuddied.

Presumably, these other developers are human beings, held together with skin, and electrified with sensitivity to the subtlety of written language. And (sit up for this part) fully subject to the psychology of that sensitivity. These words and symbols you are cranking out don’t just live in machine instruction; they echo through meetings, emails, and conversations that all translate to real human choices and actions. Once it leaves your capable hands, the quality of the decisions made around that variable, class, component, application, or system depend largely on how well the name you bestowed upon it summarizes its reason for existence.

Viewed through this lens, your christening skills can make or break a work of software.

The Bullets

There are coding conventions that ebb and flow depending on your programming dialect of choice. But these are not those. This is not about camel-casing, Hungarian notation, or brackets having their own lines. This is about communicating with other developers through code.

Here are a few pointers that come to mind:

  • Focus on what, not how. Name things based on what they do, not on how they do it. There will likely be a need for a component that provides data about your customers, long after WCF becomes a thing that even your customers know is laughable clutter on your résumé. DotNetStuff.CustomerWCFService, bad. CustomerInformation, good.
  • Take your time. Or don’t. The time you spend giving something a name should be directly proportional to the scope of the thing you are naming. Is it a string variable local to a property, holding a comma-delimited list for a few lines until it’s split up and spun into a Collection<string>? Go ahead and call it list. But that Web Application project probably should not have a namespace of MahNewKittehWebz.
  • Don’t call it New. Replacing the OrderProcessor? Cool. And that may be the NewShinyOrderProcessor you’ve got there now. But man, is the team replacing it three years hence going to have some facepalmworthy conversations. This naming strategy just shows a complete lack of respect for the space-time continuum and its future inhabitants.
  • Don’t call it a Configurator. Ever.
  • Thou shalt not append the word Object. For the love of Stroustrup. We know it’s an object—give it a name. This may be a tough habit to break, especially for those readers who were coding when the Earth’s crust was still congealing, when OOP first came into fashion. But it’s simple to overcome, nonetheless. Go ahead and name your type with the –Object suffix. Then, have a deep, cleansing breath, and rip it off. Like a band-aid. UpdateCartResponseObject becomes UpdateCartResponse. Sit still and embrace that awkward naked feeling until you realize that the new, less redundant name does the job quite nicely.

The Gun

I’ve got more bullets. With bold bits and snarky bits, some of them with entertaining/relevant links. And I would use them, but for the fact that this is not about my ample narcissism of small differences. It’s about clarity, and forethought, and choosing words carefully because they mean things. In whatever medium you choose them.

And I’d much rather just challenge you to bring these qualities to the naming in your code.

You know. For the lost children.