Monday, April 29, 2013

Pits of Success

The Pit of Success: in stark contrast to a summit, a peak, or a journey across a desert to find victory through many trials and surprises, we want our customers to simply fall into winning practices by using our platform and frameworks. To the extent that we make it easy to get into trouble we fail.

—Rico Mariani, MS Research MindSwap Oct 2003.

For anybody who has designed a system, it can get really annoying when users turn around and do really dumb things with our designs. It can be frustrating, especially when we have made our design perfectly clear (in our minds). I often overhear arguments between some of the programmers around me and our customer about this very thing. (Programmers arguing with the customer—topic for another post.)

One of my big pushes at work is to change the way we view our software. It is very easy to put blinders on and just get the job done. We deal with a lot of very pertinent aircraft data and messing that data up has major consequences. As this system was started in the 70s using COBOL, there was not a lot of screen real estate. As such, there are times when a field on the screen serves double duty, but only has a label for one of its jobs. An example is a date field on one of our screens. It can house a date, or the user can input a command to increment the count in a field next to it. Needless to say, if I find the whole thing confusing and I have access to the programmers and source, I can't imagine how hard it is to be a user.

I have getting into the "Lean Startup" movement and found a term used in Toyota's Lean Manufacturing process: Poka-yoke. It exactly describes my argument for making user screens easier to use and more intuitive. Gone are the days of needing 500 disparate fields on the screen because it is easier than creating a new screen altogether. Much like in writing code, our user interaction points need to have low coupling and high cohesion. I am, by no means, a user experience expert, but if the same situations arise where users are incorrectly using our systems, it is usually because of poor design, not stupid users. We should aim to develop our systems such that users find themselves walking in the pit of success rather than walking a tightrope trying to avoid our mistakes.

Sunday, April 28, 2013

Opening Worlds, Sharing, Teaching, Learning

I'm probably late to the game here, but I saw this Code.org short video a few days ago and wanted to share it.

Great coders are today's rap stars.

— will i. am

I personally think everybody should learn how to code. Or at least learn about how a computer operates. I am not a fan of using "magic" to explain things and I do not think that technology is so unapproachable that it has to be explained away as being magic. I was lucky enough to be taught how to code at a very young age and believe it opened up my world so much more than if I had been robbed of that time.

Sunday, April 21, 2013

Object Oriented State

It is very easy to lull ourselves into the the feeling that we are writing object oriented code, especially in languages like Java and C#, without giving much thought to what that really means. The idea behind object oriented programming is to combine behavior with state—or rather, encapsulate state within an object and expose behavior. Juxtapose this with procedural languages, like C, where state and behavior are separated. This "feeling" that we are writing object oriented code usually seems to stem from the idea that we are wrapping our code in classes.

Please, do not get me wrong, I am not bashing procedural code. In fact, I believe that procedural code, used correctly, can be easier to understand and reason through. In fact, it is used pretty heavily in object oriented programming to implement procedural pieces. That is probably why we tend to write so much procedural code, even in object oriented languages. Unfortunately, I think too many people currently view their work as object oriented programming if they are using classes. I think a distinction needs to be made because we should reason about our code more often. While I will save that argument for another post, what I will cover is a few examples of how we can make our code more object oriented, if that is our end goal.

Anemic

Without digging too much into domain driven design (DDD), command query responsibility segregation (CQRS), or other topics, I want to explore some code and compare the differences and consequences of the design. Let's start with a shopping cart that can hold products. We'll use a dictionary with the product as the key and the quantity as the value.

public class Product
{
    public decimal Price { get; set; }
}

public class ShoppingCart
{
    public Dictionary<Product, int> Items { get; set; }
}

If we stick to this (anemic) "object oriented" design and, say, try to sum the items in a shopping cart, we are going to need something like this (using LINQ to simplify the code):

public class ShoppingCartController : Controller
{
    ...
    public ActionResult GetCartSubTotal()
    {
        var cart = cartRepository.GetCartForUser();  // Use your imagination here.
        var total = cart.Items.Select(x => x.Key.Price * x.Value).Sum();
        return PartialView(total);
    }
}

Which doesn't seem too bad, I suppose. But now we need the sub total in another portion of the application. After a while, we have a few places where this code is repeated. So, we decide, simply, to refactor the code and expose a method that returns the subtotal.

A little better

public class ShoppingCart
{
    public Dictionary<Product, int> Items { get; set; }

    public decimal GetSubTotal()
    {
        return Items.Select(x => x.Key.Price * x.Value).Sum();
    }
}

It seems this is where most developers stop. There is more we can do, though, to clean up our design. If we are truly worried about encapsulation, why, oh why, can the rest of the world manipulate our dictionary of items? What happens if we decide to create a new class that holds a reference to a product and the current quantity, thus using a List instead? Now we have to go back through the application and clean it up. But, why do we even go through that in the first place? What if, instead, we all agree that (unless absolutely necessary), we will not use public properties? We could transform our cart into something like:

public class ShoppingCart
{
    private readonly Dictionary<Product, int> _items = new Dictionary<Product, int>();

    public decimal GetSubTotal() { ... }
    public int AddProductToCart (Product product, int quantity) { ... }
    public void RemoveProductFromCart (Product product) { ... }
    public void RemoveProductFromCart (Product product, int quantity) { ... }
}

Thus, we have successfully pulled all of the algorithms to perform the different functions on a shopping cart into one place. We can very easily test this code, and we can refactor it without touching the rest of our application. This allows us to follow "tell, don't ask," where we tell our shopping cart to add an item instead of asking it for the underlying items so we can, via external code, add an item or update the quantity.

Exposure

But, I bet you're wondering, how is the rest of the world supposed to know about the items we have in this cart if we don't expose the collection of items? Good question! We can create a read only view model, or a snapshot, of the underlying data that is safe for the rest of the world to use.

public class CartEntry
{
    public string ProductName { get; private set; }
    public decimal Price { get; private set; }
    public int Quantity { get; private set; }

    public CartEntry(string productName, decimal price, int quantity)
    {
        ProductName = productName;
        Price = price;
        Quantity = quantity;
    }
}

public class CartView
{
    public IEnumerable<CartEntry> Items { get; private set; }
    public decimal SubTotal { get; private set; }

    public CartView (IEnumerable<CartEntry> items, decimal subTotal)
    {
        Items = items;
        SubTotal = subTotal;
    }
}

public class ShoppingCart
{
    private readonly Dictionary<Product, int> _items = new Dictionary<Product, int>();

    public CartView GetView()
    {
        var items = _items.Select(x => new CartEntry(x.Key.Name, x.Key.Price, x.Value)).ToList();
        return new CartView(items, GetSubTotal());
    }
}

It may seem like a lot more code, but when you see how much repeated logic and code you pull into one place, and how much more testable this is, it will be worth it. Of course, there are always exceptions and use cases when something like this doesn't make sense. Of course, when those use cases are found, it is usually because one has reasoned about their code and has a good reason not to put in the little bit of effort to truly follow an object oriented approach.

Friday, April 19, 2013

Using Strongly Typed Properties

When my team and I started to port a Web Forms application over to the MVC side of the ASP.NET stack, I specifically set out to solve an issue we continued to run into. We have these fields on the screen that tie back to some property on an underlying "program," usually exposed as some sort of primitive, such as an int, or string. There are many these properties are found in many programs and usually follow some sort of business rules. Let's say one of these properties is called a Foo. In the Web Forms implementation, we would see something such as the following.

public class SomeProgram : Program
{
    public string Foo { get; set; }
}

public class SomeOtherProgram : Program
{
    public string Foo { get; set; }
}

A "Foo" has a very specific meaning in the domain of the application. In implementation described above, it is very easy to accidentally pass the wrong string to a property because you don't get a red squiggly telling you that you just set that "Foo" with a "Bar" because they're both just strings.

Instead, in our rework, we created a base class called CommonType. (These are basically just value types in the domain driven design world, in that we don't care about their individual identity.) From that CommonType, we have created other "types" to represent our data. So, instead of our properties look like they did, above, we now have something else like this:

public class SomeProgram : Program
{
    public Foo Foo { get; set; }
}

public class SomeOtherProgram : Program
{
    public Foo Foo { get; set; }
}

Now we can't accidentally pass in a "Bar" to a "Foo" without some sort of conversion and we get the help of the compiler to tell us we're mapping things incorrectly. The other benefit of doing this is that these fields need to be represented the same way in the UI. Instead of having the same hand-coded (usually inline) styles, we can create editor templates, model binders, and tell MVC how to play nicely with our types.

@model X.Y.Z.Program
@using (Html.BeginForm())
{
    
}

Now we have one, and only one, place that defines what a "Foo" looks like in the application instead of relying on Find-All.

Tuesday, April 9, 2013

Agile Software Development

As I am currently in a transition phase out of my current job, I have been looking at my résumé a lot. I noticed that I do not have the word "Agile" on it at all. This is interesting to me because it was something that I tried to promote just a few years ago. I think that has a lot to do with how I view software development now. While listening to a .NET Rocks round-table podcast a few months back, the question, "Is agile dead?" was posed. The answers were pretty interesting, but the one that stuck out to me the most was something along the lines that agile isn't dead, it is just the way we do software development now.

On the shows's page, a listener, "bashmohandes," made a comment that I have been thinking about for a very long time:

I don't think Agile is dead, but I think it got ruined by companies that think they are doing it but they are just fooling themselves, or using it as an excuse to keep changing requirements on the poor developers.

Most of the places I worked at, have some remnants of agile methods, like daily scrums, but pretty much nothing more, no fixed size sprints, or spring planning meetings, or retrospective meetings at the end of the sprint, or pair programming.

Specifically, that companies are "using it as an excuse to keep changing requirements." While I am leaving my current position, this is something that I have been struggling to keep from affecting my team. There are a few people in place who could fix this—but they don't. In fact, I don't think they know how to. It was recently told to me that we develop software in "a more waterfall approach." This made me laugh a bit as we don't even follow waterfall. That whole requirements gathering thing is a joke. The developers are currently expected to read the customer's ever changing mind and it is difficult to pin them down.

My current project has been around since the 70s and supports a major command of the USAF. The failure of the application means that troops and supplies are halted and commanders can lose situational awareness of their fleets. But, even with how critical this application is, there is hardly any structure when it comes to defining requirements and paving a path forward. Listening to the podcast really hit home. So many managers seem to want a "spray on agile" solution as if it is some sort of magic. Well, it isn't and "spray on solutions" don't work. In fact, they make things worse.

On the web development side of the shop, I have been able to focus everybody's attention on unit testing, pair programming, and actually talking with the stake holders. Unfortunately, the planning portion is still lacking. Our side of the house has been strategically made void of information silos. Unfortunately, on the COBOL side of things, they still exist. Each COBOL programmer works at their own pace, makes changes, and throws them at the web team to handle. Cause we're agile.

While I believe that true agile is the way to go in software development, I also take a pragmatic approach to things. When initially implementing an agile methodology, it is usually very difficult to get everybody on board, up front, and willing to make all the changes necessary to truly support the change. But, it is important to keep going, keep adding things, keep changing, keep growing, keep learning. It really takes a substantial commitment from management, the customer, and the development team, to realize that they are all in it together.

Thursday, April 4, 2013

Personal Brand - Part 2

In part one, I gave a little back story about myself and how, by failing to manage my "personal brand," I set myself up for a really rough transition out of my current job. One of the great things about owning up to your own mistakes is that you can then do something about it. It is yours to own, it is yours to fix.

I have resolved myself to doing a few things this year to both help promote myself and showcase my capabilities, but to also give back to those who have helped me. I have used a lot of open source, but I have failed, miserably, to give back. That is really wrong and something I want to turn around this year. Really, without thinking, it is easy to pull down everybody else's hard work, through NuGet, and have an app up and running so quickly these days. It is very easy to forget that you're being a heavy consumer, even when you're producing.

Well, I would love to get involved in open source and actually contribute something. My hesitation has been mostly driven by my current employment situation. If something I wrote in open source looked like something I used at work, it would cause some issues. Well, I am on my way out, starting a new chapter, and to hell with it. I want to give back to the community and, hopefully, help somebody out there on the interwebz have a better development experience.

Something else that I have failed to do was keep some sort of blog. It is a bit narcissistic to have one and so I have always had trouble with the idea of putting my random thoughts out on the wire and expecting people to want to read it. But, I realized, this is for me. I am writing to keep track of my own personal progress. It is a way for me to measure my personal growth, keep track of things I'd otherwise forget, and, again, hopefully give back to somebody out there.

While I would love for this experience to produce some magical employment opportunity in the future, that's not really what it is about.

So, I will be working to blog more, tweet more, get involved in open source, and be an all around more giving person on the internet (and IRL). If you have a project on which you want help, post a comment, send me an email, hit me up on Twitter, something. For the time being, I will probably troll around GitHub and look around some more. I really like what Mark Rendle is doing with Simple.Web, so I might fiddle with that a bit until I settle down on a project or two.

I realize that my "lack of experience" on my résumé is going to haunt me for a while. I could, technically, have skipped the Air Force and just focused solely on me and what I want, but that wouldn't have been any good either. So, here I am, taking my first steps to being a better person, managing my own personal brand, and expecting to make a change—somewhere.

Wednesday, April 3, 2013

Personal Brand - Part 1

I have been using computers, programming, and enjoying technology since I was a very little kid. I recently started to look for a new job and realized, very quickly, that I have failed to "manage my personal brand." Here's a little story on how I came to realize it, and, in part two, what I plan to do to fix it.

After having successfully built up a customer base, while serving in the US Air Force, and later transition from military to civilian life on this same clientele, I have found it extremely difficult to explain to employers why I am not a "Junior Programmer." Looking at my résumé, it would appear that I only have three years of development experience. Which is really hard to explain. Really hard.

I successfully built up a great customer base that supported me as I transitioned out of military life to civilian life. Upon deciding to have a child, my wife and I found it prudent for her to come home and me to "get a job." We really wanted a few stable things like healthcare and the ability for me to work a normal 40-hour work week. Had we held off on expanding our family, I would probably still be growing my consultant work and building up a product to bring to market.

Back to work...

Upon posting my résumé online, I received about 20 phone calls from recruiters and had a new job lined up within less than 24 hours. I found myself working back on a military base working on an application that supports a major command (MAJCOM) in the Air Force. I joined the team in their rush to complete a website written using ASP.NET Web Forms with three months left in their year long development cycle. It was a pretty nasty beast with no structure—but it was a "job."

After hitting the release date (which was actually considered a miracle) we went into maintenance mode. The team started to fall apart and, eventually, everybody quit a few months later. Well, everybody except me, the new guy, and a federal employee we worked with. Unfortunately for us, the work load didn't change and the customer still expected the continued support of the application. I became the "lead," as a contractor with the recommendation and support of the "big boss."

Over the next year, I was able to build up a new team and actually competed for, and was hired as, a federal employee. This gave the team some stability, and me the opportunity to change things. I was able to untangle the ball of mud into a pretty elegant ASP.NET Web API and MVC3 solution. My new team was very supportive and open to my guidance. Together we created a composable system that obfuscated the 30+ year old COBOL code and started to drag functionality out of the legacy monolith into C#.

Needless to say, I have been working heavily in .NET for a long time and using, almost exclusively, C#. I know it very well and use my own personal time to research and increase my knowledge. I write code, even when I know I'm going to throw it away, just to practice and learn something new. I explore open source, non-Microsoft frameworks, along with the stuff Microsoft hands us developers. I do not believe that Microsoft has all of the answers and am not a developer that follows them blindly (when able).

Transition

I am now going on a combined two years on this project and was always a bit leery of writing a blog or exposing too much about what I do. My project is not accessible to the public, but it is used world-wide by people from "wrench-turners" to executives in the military. If my application were to suddenly stop, it can keep aircraft from flying, personnel from being moved, and people from working—all over the world. But now I'm leaving.

I decided to stay in the private sector a bit more before jumping back out to form my own company, again. And, after having successfully managed the development and life-cycle of a multi-million dollar application, I am having to answer questions about the difference between a class and an interface. The interviews feel like I won a spot as a player on a very poor C# quiz show. They are very shallow, at best. But I have pushed on through them.

Rejection

Today, I received a rejection notice for a "Software Engineer III" position, from a recruiter:

Hi Jim,

We got feedback from your submission at [redacted]. The hiring manger said that from his perspective you are a little light on the C/.NET development side. He broke it down a little more for us, citing the COBOL application interface, VB6 and independent front end web application work and that he has worked with many engineers in this type of environment for many years. That being said, he needs someone with a more development heavy C/.NET background.

I'll keep looking and will let you know the next time I have a position that suites your skillset. [sic]

I don't even write COBOL! Or VB6 for that matter. Oi! But it is enough to motivate me to manage my personal brand.

Tuesday, April 2, 2013

Introduction to the Decorator Pattern

One of my favorite software development patterns is the Decorator Pattern. After having taken on so-called brown-field projects, and discussing design patterns with others, I notice so many areas where this pattern could have saved a big ball of mud from forming. It happens very often, even when code starts off cleanly written, that new requirements are added. Without much thought, it is easy to go into the areas affected and edit the classes that have already been written. (Very quickly violating the Open/Closed and Single Responsibility (SRP) principles.)

We will start with something simple here just to get a feel for the pattern itself. So, without further ado, let's take a look at some code. Let's say we have a class called Handler and its job is to handle some command given to the system. We will avoid the use of generics for now to keep it simple.

namespace Patterns.Decorator
{
    public abstract class Handler
    {
        public abstract void Handle (object command);
    }
}

And let's say we have some concrete implementations of Handler that each talk to the database to update some record. (Null checks avoided to simplify the code.)

namespace Patterns.Decorator.Concrete
{
    public class FooUpdater : Handler
    {
        public override void Handle (object command)
        {
            // Foo is just some made-up class to give this method a bit of a body
            if (command is Foo)
            {
                var asFoo = (Foo)command;
                var record = database.Load(asFoo.Id) // get a record from the database
                record.Bar = asFoo.Bar;              // update the record
                database.Save(record);               // and save it
            }
        }
    }

    public class BazUpdater : Handler
    {
        public override void Handle (object command)
        {
            // Baz is just some made-up class, as well
            if (command is Baz)
            {
                var asBaz = (Baz)command;
                var record = // Okay, pretty much the same thing as above
                ...
            }
        }
    }
}

Everything is working well, but this was quickly implemented to get it in front of the customer. The functionality has been "blessed" and we realize we need to log exceptions. What I have seen, all too often, is something such as:

public class FooUpdater : Handler
{
    public override void Handle (object command)
    {
        try
        {
            if (command is Foo)
            {
                var asFoo = (Foo)command;
                var record = database.Load(asFoo.Id) // get a record from the database
                record.Bar = asFoo.Bar;              // update the record
                database.Save(record);               // and save it
            }
        }
        catch (Exception ex)
        {
            ErrorLogger.LogException(ex);
        }
    }
}

For a very simple system, this might work just fine. But this is not a maintainable solution. We have just broken the Open/Closed principle along with SRP. Our Handle method has taken a dependency on ErrorLogger (good luck testing this method now) and has to be changed every time we want to add some functionality. Even worse, that same boiler-plate code has to be copy-and-pasted all through our project. Yuck!

One way to fix this is to rewrite the Handler class:

public abstract class Handler
{
    protected abstract void HandleImpl (object command);

    public void Handle (object command)
    {
        try
        {
            this.HandleImpl(command);
        }
        catch(Exception ex)
        {
            ErrorLogger.LogException(ex);
        }
    }
}

But then our base class becomes flooded with all sorts of mixed behaviors (it tends to become a god object) and quickly becomes a maintenance nightmare. Imagine if we wanted to add some functionality that logged some information based on the type of command given. We would probably find ourselves with a nasty, brittle, switch statement. Once it was written, we would never want to add functionality because it would be too scary. You can't even test this mess to get some sort of regression tests without a bunch of pain. (No wonder some people don't like writing unit tests!)

Fear not! The Decorator Pattern is here to help save us from this unwieldy jumble of code. Let's think of each piece of functionality that we were trying to implement. They sort of wrap around each other and form a ball, kind of like decorating a cake. One layer of frosting, or functionality, at a time. We can easily achieve this same effect by pulling out the layers into their own classes that look like the original base class. But, instead of having a default constructor, they will take in a Handler, so we can layer functionality.

namespace Patterns.Decorator.Concrete
{
    public class FooUpdater : Handler
    {
        public override void Handle (object command)
        {
            if (command is Foo)
            {
                ... // Do the work like we originally did, above.
            }
        }
    }
}

namespace Patterns.Decorator.Logging
{
    public class Logger : Handler
    {
        private readonly Handler _decorated;

        public override void Handle (object command)
        {
            try
            {
                _decorated.Handle(command)
            }
            catch (Exception ex)
            {
                ErrorLogger.LogException(ex);
            }
        }

        public Logger(Handler decorated)
        {
            _decorated = decorated;
        }
    }
}

Now to add the logging functionality, we can leave the original FooUpdater class alone and just wrap it with new functionality. Easy as cake!

var handler = new Logger(new FooUpdater());

So, we have seen how to add functionality to a system without modifying the code we wrote originally. Of course, requirements change and we might need to modify the original code—but we have crafted our solution so that the original code only needs to be modified for one reason (the business rules have changed). Using the decorator pattern we can safely maintain the Open/Closed principle and SRP. Now we won't be so afraid to add that next layer of functionality.