Friday, April 17, 2009

What is strategy?

Strategy is the process of choosing a broad goal, creating measurable objectives, executing a plan, and seeing if your execution is driving towards the objectives. It sounds incredibly easy, yet very few people are capable of actually conducting themselves in this manner in a professional context. You could ask many reasons why, but that wouldn't help you make the change.

Agile development methodologies are all about coming up with short, concise, measurable objectives in the form of a lightweight spec, such as a user story. I don't know if it is beneficial for team members to really get their head around the mechanics of how an effective strategy works. I think one of the outputs of effective strategic execution is predictable results, such as being able to forecast a team's velocity.

I'll tell a little parable that illustrates how even in the simplest of situations, our emotions and other psychological inputs can distract us from executing our strategy. Anyone who knows anyone from New York City and its environs will be amazed to find that New Yorkers talk about trains the way people in other cities talk about traffic. And anyone who lives in the boroughs is required to understand the nuance and intricacies of the train schedules on the weekend.

My fiancee has been spending a lot of time with me in NYC and I've had to explain all of my strategies to her for effective train riding. Check out the system map if you're not familiar. Our apartment is in Ft. Greene right near one of the busiest subway stations, Atlantic-Pacific. From our house you are within 3 blocks of the A, B, C, D, Q, G, M, N, R, 2, 3, 4, and 5 trains! So the question is often, which train should I take? Well, the entrance that is closest to our house takes you right down to the platform where the B/Q can be caught, so we almost always take these two lines.

So that right there is an example of strategy in action: our goal is to wander the least and catch a train in the least amount of time that will get us to our destination in the least amount of time. The N and the Q are probably the 2 best trains that go through the station, but a stupid strategy would be to go downstairs and if the Q isn't there, go get the N - this is because in the time it takes you to walk to the N, you will probably miss the B or the Q. If I am trying to go somewhere that is only serviced by the Broadway line, I will still just wait for the Q (unless of course it is a weekend in which case I will walk over to the D/N platform since those trains, while requiring an extra walk, are more reliable on the weekend).

Now my office is over on 26th between 6th and 7th. The very closest station is in fact the 1 train station at 7th ave and 28th street. But the 2/3 is really slow and I have to transfer from the 2/3 to the 1, so this route is automatically out of the running. The next closest is the F train station at 23rd and 6th, so if I catch the B train, I have a strategy: if I pull into Broadway/Lafayette or West 4th, and the F train is pulling in at the exact same time, such that I can catch the F with no waiting, it is faster to take the F. Otherwise I just stay on the B and take it up to 34th street, the next stop after W. 4th. While this is a longer walk, waiting for the F is longer.

Does this make any sense? I've optimized my journey for the MOST important objective, which is to get to work in the least time possible so that I can sleep later and eat breakfast at home which is healthier than eating a bagel and cream cheese from the deli. The objective of getting to the station that is closest to my office is less important than getting to my office quickly. Doing the extra walk from 34th street also serves a nice-to-have objective of trying to get as much exercise as I can even when I don't go to the gym.

There are myriad choices to get from my house to the office, and all of them will eventually result in my arrival at work; however, I've clearly identified an objective, which is different from a goal since it is measurable, which is to get to work in the least amount of time possible for the least amount of money. There are many decision points along the way, but by limiting the number of branches in the decision-making process, I have arrived at a very consistent formula. If I take the B or the Q, I know I can be at work, door-to-door, in about 40 minutes. Taking the F may reduce this time by a few minutes, but the risk of sitting on the F train platform for 5 minutes (which happens maybe 1 out of 3 times I choose to do so) is not a risk worth taking.

Teams doing work need to limit their choices and come up with a consistent tactic to getting work done quickly by choosing the right goals and objectives. Over and over again, I find the most effective way to trim time off of projects getting done is to force developers to give me code that I can acceptance test on the build host. I generally don't consider any of the sub-stories of value, I only care about stories like, "As the public, I can see this website feature do something." Plumbing may have been required to get there, but the surest way to know if the plumbing, chores, sysadmin crap, and all other work required to get paid - because that is the mother of all objectives - is if I have a working website that lets me exercise the story in question. Letting broken untestable or unacceptable (meaning work that can not be acceptance tested) sit around is classic waste in the lean sense of the word.

Wednesday, April 15, 2009

Agile Contracting

Oh man, this topic is a doozy. Customers want to know how much something will cost and when it will be done without knowing what it is we are really going to end up doing. When you suggest that we will discover things and course correct, they stare at you blankly and ask if that means they are getting a discount. Customers generally don't want to have to think, and they want to shift the responsibility of designing their business model onto you, the contractor, because bless their hearts, they probably don't even have a business plan that would let them articulate their business and revenue model as it applies to the work they want you to do.

Having a consulting services based business means that your business consulting service model must be laced up and iron clad. You need to be the Delta Force that your customer is looking for. When you are a small business trying to keep all your customers happy, doing operations and support, figuring out your own revenue model that's required to support your existing client base, while at the same time figuring out how to grow your company to cover your new expenses that have emerged from your own success... it's really hard to do this. This is why most small businesses fail. An added challenge is when your business is small and there are limited numbers of partners, the partners tend to be the business development team, the sales team, the account execs, the PMs... and those roles have conflicting agendas that can make course correction in the middle of a project very hard. Sales people don't want to admit that the company's capabilities are a work in progress.

Here are some very cool articles on alternative contract models. The fixed cost, fixed scope, fixed time model ALWAYS fails without a change control officer pounding the client relentlessly, which often results in an unhappy client; on the other hand, if you don't pound them with change control, they eat into your margin, for us, typically by 50% of our margin. We desperately want to be fixed scope bucket, but varying content of bucket; we want to be fixed cost and fixed time, where we append the emerging requirements into a new bucket of cost and time.

Friday, April 10, 2009

Rails has no application context

Something my developers have been complaining about lately is the difficulty in creating a generic dependency injection framework for a project with a lot of different plug-ins. I am asserting that there should be a generalized mechanism to set properties on a Rails domain model, rather than allowing plug-ins unholy access to reek havoc on my model objects.

We have a use case where we want to be able to inject different implementations for the same interface. The idea is that we are using attachment_fu to decorate models, but we want to be able to store attachments in a different persistence mechanism (currently local filesystem or Amazon S3). We've implemented a generic framework as an engine that depends on attachment_fu to handle the attachments. For a given client project, we'd like to able to inject the implementation for S3 or filesystem persistence, but since attachment_fu totally hacks our objects to bits, we have to write some exotic and smelly code to configure a given model to do what we want.

This is not the first time they've lodged this complaint, which is more or less that no matter how much (by much I mean well-defined, encapsulated, well designed OO etc) of an interface one of our in-house APIs surfaces, we are always already limited by the hackers who infiltrate our code with no contract. Plugins like attachment_fu offer no contract, they simply save the desperate ruby hacker from having to write lines of code, but the end result is a totally non-transferable hunk of smelly spaghetti code.

Perhaps Rails just doesn't support our over-arching design goal, which is the ability to write one piece of code to handle the use cases all of our clients ask for on every project we do. Maybe it's faster to just re-write the same code over and over. I called this article "Rails has no application context" because I am used to working in an environment like Spring where I can request any implementation I want through the application context. Objects communicate through an interface and there is no shared knowledge of implementation details. I want this same kind of service bus in Rails, where objects can register themselves and be available, and other objects can request an implementation of an interface and know that the required operations (eg save to storage mechanism) will be available without having any idea about implementation details of each other. Jaroslav Tulach calls this a "Teleinterface" which I think describes this situation accurately.

I've proposed to my development team that we create some kind of proxy for attachment_fu to rape as the sacrifical vigrin, rather than treat our whole domain model as an open harem. We must repel the godless Romans from our code. We can create some kind of proxy object that gets wired up with the attachment_fu hooks, and this object can then act as an API for our code to consume.