Sunday, May 2, 2010

Coding Style Preferences

I recently did a little poll on twitter and in my office to get a feel for what people's coding style preferences were.  The fun thing about coding style preferences is that they are completely irrelevant, and yet a topic that people can easily get pretty passionate about.

It was only a little poll, with 35 people responding to these few questions:

Curly braces?
  • On new line
  • On same line
Spaces in control statements (if, foreach, etc)?
  • Spaces outside and in ex: if ( this.HadSomeCandy )
  • Spaces inside only ex: if( this.HadSomeCandy )
  • Spaces outside only ex: if (this.HadSomeCandy)
  • No spaces ex: if(this.HadSomeCandy)
Spaces in method calls?
  • Spaces outside and in ex: someone.ShouldJustDecide ( "what", "is", "right );
  • Spaces inside only ex: someone.ShouldJustDecide( "what", "is", "right" );
  • Spaces outside only ex: someone.ShouldJustDecide ("what", "is", "right");
  • No spaces ex: someone.ShouldJustDecide("what", "is", "right");
Spaces in method declaration?
  • Spaces outside and in
  • Spaces inside only
  • Spaces outside only
  • No spaces
Spaces in method calls with no args?
  • No space ex: someone.ShouldJustDecide();
  • Space ex: someone.ShouldJustDecide( );
How many spaces in indentation?
  • 2
  • 4
  • 8
And here are the results:



So, clearly, the winner is spaces outside/no spaces as in:
if (who.Cares("about coding style?!");

An interesting observation here is that the people who "don't like spaces" are very consistent in their preferences whereas the people who "do like spaces" are much more varied.  This is evident in that of the 22 people who voted for spaces outside only in control statements, 19 also voted for no spaces in method calls.

Note that only 25 people answered the question about spaces in indentation because I added it to the poll later.  I expect the results would have been much different because it was the people from my office who didn't get to answer and our internal standard is 2 spaces.

For curly braces it was 22 to 13 in favor of braces on a new line.

There were answers for just about every combination, no matter how weird.  For example, some people put spaces outside and in for control statements but no spaces in method calls.

The sample size of this poll is too small to actually mean anything, but it is still interesting that the preferences line up pretty closely with Microsoft's coding style standards.  I didn't verify this, but I wonder if this could be influenced by Visual Studio's default code style settings.

Personally I was very much in the minority here.  For the last five years I've been a spaces outside and in/spaces inside guy as in:
if ( who.Cares( "about coding styles?!" );

I've also been a 2 spaces guy and if you go back to college I was a curly braces on the same line proponent.  I started doing the curly braces on a new line when I started full time at my job.  I recently tried curly braces on the same line when I started learning jQuery and I have to admit, I didn't like it anymore.  Could be just because my javascript is still pretty ugly though.

I'm also starting to second guess the whole 2 spaces thing.  I always preferred it because it made it so you could see more code.  But now that I've embraced the SOLID principles, if the lines of code in my methods were so indented as to cause a problem reading them, I'd suspect a "design" problem with that method.  And I'm starting to think that 4 spaces would make a pretty big readability difference, since it would be much easier to spot where indentations start and end.  I think its especially important if you do curly braces on the end of the line, or if you're writing Python or Haml.

Finally, I always liked the spaces in control flow because I believed it made it easier to read.  But when I was preparing this poll I wrote the different styles out side by side and I started to wonder if the spaces actually bring out the "noise" of the different characters...  I'm still not sure about this one.

This whole exercise also made we question WHY there is so much possible variation in the languages.  Wouldn't it be nice of the details of the language were done in such a way that there was 1 right way to do it and we didn't have to concern ourselves with silly details like where to put spaces?

Monday, April 26, 2010

View-Model design question

Here's a design question for you!

Lets say you are working in ASP.NET MVC 2 (or your favorite MVC web framework).  Lets also say you have a nice rich model.  Your controllers have to fetch the model objects and get that data to your view.  How do you do that?

There are a bunch of ways:
  1. Pass the model directly to the view
  2. Create a "View-Model" class and put a property on it that exposes the model
  3. Create a "View-Model" that completely hides the model behind properties of its own
And there are a bunch of variations on those too.  But those are the main options.

The best thing about #1 is it's as simple as can be.
#2 is almost as simple as #1 but adds the ability for you to create other custom properties on the "View-Model" object that can perform various operations for the view.  For example, you might format values, or retrieve the latest object from a list, etc.

The downside to these two options is your View is directly coupled to your Model.  This might become a problem if you end up with lots of Views that depend on the same Model, or if the Model keeps evolving and being refactored over time.

That's where #3 comes in.  By creating all new properties on the View-Model, you're basically applying the Dependency Inversion Principle and saying, "This view needs this data, I don't care where it comes from as long as someone provides it."  You will now need some form of mapping layer to get the data from the Model to the properties of the View-Model.  This is more work, but it's also nice.  When the Model changes, you only need to update the mapping, which is dramatically easier than digging into lots of HTML and finding what could be many references to your properties.

Now, that said, there are still lots of changes that will require you to make changes to the Model, View-Model, and View.  Any change that is a change in the *meaning* of the Model will cascade this way.  But there is a whole set of changes that won't cause this update cascade.  Like any refactoring of the Model for example.

The obvious downside with #3 is more code and more work (Though tools like AutoMapper certainly help).

So, how do you know when to apply which pattern?  Is one pattern always better than the others, or does it depend.  And if it depends, on what?  And how do you know when it's time to switch from one to the other?

Thoughts?  Experiences?

Monday, April 19, 2010

SRP and complexity

The Single Responsibility Principle (SRP) is probably the most important concept of good design.  But even once you know about it, and have read up on it, and seen countless blog articles describe and reference it, you may find yourself hesitant to actually follow it in real life.

The usual argument against it is that it seems like it might increase the complexity of your code.  Lets look at an example of applying SRP to a method.

public void UpdatePrimaryThingStatus( string status )
{
  Thing primaryThing = null;
  foreach( Thing t in something.AllThings )
  {
    if ( t.IsPrimary )
    {
      primaryThing = t;
      break;
    }
  }

  if ( primaryThing != null )
    primaryThing.Status = status;
}
There's nothing _wrong_ with this code, but it doesn't really follow SRP because the method is updating the primary thing's status, as advertised, but it's also finding the primary thing.  Lets factor out the finding of the primary thing into its own method:

public void UpdatePrimaryThingStatus( string status )
{
  var t = GetPrimaryThing();
  if ( t != null )
    t.Status = status;
}

public Thing GetPrimaryThing()
{
  foreach( Thing t in something.AllThings )
  {
    if ( t.IsPrimary )
      return t;
  }
  return null;
}
Notice how much code actually disappeared here.  And notice how simple each method is.  But, we did add a new method to the class.  Do we intended to reuse this method?  That depends, it IS a useful method that could easily be reused, but since we didn't have it already, lets assume we don't need to reuse it right now.  So yes, we simplified the code in the individual methods, but by adding a new method we've increased the complexity of the class.

We should probably ask why adding a new method is a problem.  It's only one new method!  It's well defined with a single responsibility, with an intention revealing interface, and simple code to boot.  Why would we think this is going to increase the complexity of the class?  Probably because we're used to working with classes that are thousands of lines long with lots and lots and lots of methods!  So yes, if you're applying SRP to your methods, but not to your classes, things might get a little complex.  But make sure your classes have a single responsibility, and you'll find that this wont be the case anymore.

OK, so if our classes are following SRP, then we'll be breaking large classes into more smaller classes.  But now we have lots of classes!  Doesn't that make our code more complex?

This same pattern will follow right up the chain through namespaces and assemblies...  is this getting out of control?  What's the solution?

The solution is cohesion!  You can add lots of small classes as long as they are all part of a cohesive whole.  This is actually a really beautiful thing.  If your classes are well organized, and obviously form a cohesive unit, you get an amazing benefit.  Lets say you need to go into the code and find a bug.  You know what area the bug is in, even if you don't know exactly what it is.  There may be 20 files that make up your code, but you'll probably only need to crack open 3 or 4 of them to find and fix the bug.  And each file you do open will be understandable, dare I say, easily understandable.

You may think there is still a problem in understanding the WHOLE.  To understand how it all works, don't you now need to open all these little classes and figure out how they all work together?  Yes and No.  Again, I think the fact that each class has a clear single responsibility (and therefore an intention revealing interface) means you can actually understand the WHOLE and read less code than if you had it all squished into a single class.

So, whatever you do, don't let fear of complexity drive you away from SRP.

Monday, April 12, 2010

Framework Disease

A lot of software engineers have a Computer Science background.  My college education, for example, included  the standard things like Data Structures and "Operating Systems."  It also included some cool things like Artificial Intelligence, Peer to Peer, Automata Theory, and Evolutionary Computation.  I was also fortunate enough to have the opportunity to participate in some research projects as well which included Mobile Agents, Evolutionary Computation, and Swarm computing.

These things are cool.

But now I spend my time figuring out how to get data from a UI into a database and back again.  That's basically the bottom line of "Enterprise Application Development".  Surprisingly, there are enough challenges in this space to keep you busy for a very long time.  And while the topic itself doesn't have a lot of sex appeal, the work is actually amazingly broad, even just from a technical standpoint.  And once you add the "business" concerns in, it has the potential to become very interesting indeed.

But still I'm a computer scientist, and I'm inexorably drawn by computer science-y problems.  In the Enterprise space, the most computer science-y problems tend to be those of building "frameworks."  And what I mean by framework, is re-usable code bases that developers use to avoid having to write the same (or similar) code over and over again.

Frameworks are to some people as cat nip is to cats, or street lights are to moths, drugs to drug addicts, or cigarettes to smokers, or...  Some people loooooooove building frameworks.  They are always on the look out for an opportunity to build a framework.  At the first sign of duplication, or recurring pattern, you can see the light in their eye... framework!

I call this Framework Disease.  Frameworks are tricky.  They can be huge time savers.  And they certainly are fun to work on, since they're so computer science-y.  But at the same time, they can be real time wasters.

Sometimes the problem you are trying to solve with a framework simply isn't worth the time it takes to build the framework.  This could be because all the framework does is replace some standard boilerplate code that could easily be copied and pasted or generated.  In these cases, centralizing the boilerplate can actually be a bad thing because you're forcing every use to be identical forever.  Just because they are the same now doesn't mean they always will be, or always should be.

Other times the framework ends up being written in such a way that it actually becomes a problem.  This can happen when the framework starts limiting what you can do, or when it continues to grow and grow and grow, or when the complexity of the framework obscures the simplicity of the problem being solved.  When this happens you're spending more time working on and fighting with your framework than you are on actually getting things done.

Another problem with frameworks is the tendency to build them too soon.  If you set out to write a framework without having seen plenty of examples of what your framework will be replacing, your framework is probably doomed.  To be really successful, you have to write the code your framework will replace in a number of different places.  If you don't, you'r just guessing about what should be abstracted into the framework.  This means you really don't know what should go in the framework, nor where the framework should be flexible or where it should be rigid.

I have personally fallen into all these traps many times, and just about everyone I know has suffered from a bit of Framework Disease at one time or another.  It is very contagious.

I think Framework Disease is a symptom of not being connected enough with the goals of the development effort.  At Codemash, Mary Poppendieck told a little parable that went something like this:
A philosopher walked into a quarry and saw three people working with pickaxes.  He walked up to the first man and asked him, "What are you doing?"  The man irritably looked up and said, "I'm cutting stone, what the hell does it look like?!"  The philosopher moved on to the second man, asking the same question.  "I'm making a living for my family."  Finally the philosopher asked the third man, who responded, "I'm building a Cathedral!"
The third guy clearly understood the context of his work.  I think a lack of understanding of the context of work is frequently what leads to Framework Disease.  Passionate people in particular are susceptible to this.  Without a broad understanding of why you are doing what you are doing every day, how can you possibly stay focused on the important things?  How can you possibly stay energized?

So if you find yourself exhibiting the symptoms of Framework Disease, step back and ask yourself, "If I'm not building a Cathedral, what am I building?  And does this framework really further that goal?"

Monday, April 5, 2010

Passion

I think there are two qualities that set really great developers apart:
  1. Technical competence
  2. Passion
Pretty much in that order.  If Bob has strong tech skills, it means he can solve complicated problems to a reasonable level of quality independently.  But if he is lacking passion, it means he wont be looking for opportunities to improve, or to push the envelope on issues like code quality, cleanliness, productivity, etc.

If Bill has a lot of passion, it means he'll be on the lookout for ways to improve.  Both in his own work, and his team's work.  But if Bill doesn't have the technical competence to back it up it means he's simply unreliable.  The impression will be that he pays lots of lip service to quality and improvement but never manages to actually deliver any.

Bennie, on the other hand, might have both of these qualities.  This makes him reliable and constantly improving. And not just improving himself, but improving those around him.  Bennie is the guy who's likely to not only complain about some "policy" his office has that he feels is hurting more than helping, but to actually work on getting that policy changed.  Effectively, Bennie is a leader.

I think people with passion naturally end up leading, regardless of whether they are in "leadership" roles.  You don't have to be the boss to influence how your company works.  And you don't have to be the team lead to influence what technologies get used and how.

However it is this fact that makes passion a double edged sword.

Passionate people are more likely to challenge the status quo.  Which is good.  Unless they are challenging it in ways that actually hurt their team or hurt their company.  This runs along the same lines as some issues I discussed in an earlier post called Engaged Employees.  In a nut shell, if the priorities of the passionate people don't line up with the priorities of the business, you've got trouble ("With a capital T.  And that rhymes with P and that stands for..." Passion?).

When the passionate people become dis-engaged, there are two likely outcomes.  They might start "farting around" with "improvements" that don't actually help the team or the business accomplish any of its goals.  It is probably still true that these "improvements" are "good" in their own context.  But in the context of the business, they might actually be "bad," or possibly just unimportant (and therefore a waste of time).  On the other hand, the passionate people might decide to simply checkout.  They might decide to put in the minimal amount of effort possible, with an attitude of "screw those guys."  If just one person was acting in either of these ways, it wouldn't be that big of a deal.  But when it's your passionate people, it can lead to much more trouble.  These are your leaders after all, and their attitude and behavior rubs off on everyone else.

A company plagued with dis-engaged passionate individuals (like Bennie) would probably like to trade them all for simply technically compete people (like Bob).  The Bobs would stop causing so many problems and stop challenging everything and stop being in such a bad mood all the time and just get their work done.

But we have to ask, what has led the passionate people to be so removed from the goals of the business?  I think there is always a simple one word answer to that question: Management.  The book First Break All The Rules makes the case that a managers job is simply to bring out the best in his people.  And not the best out of context.  If you're an amazing yo-yo player but you program for a living it's not your manager's job to bring our your best yo-yoing.  Obviously.  It's his job to bring out your best in the context of the goals of the business (What a Programmer Wants in a Manager).  If your passionate people don't know what the priorities of the business are, or if they can't figure out what they could do today to have the biggest impact on the company, then management has messed up somehow.

But just because management has messed up doesn't mean we get to blame them and call it a day.  It doesn't mean we can just give up, stop trying, decide not to care, or adopt a bad attitude.  That is the path to the dark side.  As Bobbies, we have to do what we've always done: Fix it!  This is going to be harder for us than, say, designing a better data layer.  This is now a people problem.  And as technical nerds, we are probably not the best suited individuals to address people problems.  But sometimes we have to embrace the circumstances life throws at us, however uncomfortable they may be, and we have to grow up, step up, and fix it!

Thursday, February 25, 2010

Quality Code

A month ago or so Jeremy D. Miller wrote a blog post where he briefly, but effectively, tackles the issues of why writing good code is important. I've written about this in the past as well. Now, I think this is one of those issues that no one would REALLY argue against, but that we all know lots of people don't FULLY agree with or understand.

I don't think anyone would argue that bad code is better than good code. But I think people (developers and business people) misunderstand how important good code actually is. This issue is very near and dear for me because I have quite a history with bad code. Really bad code... So figuring out what good code looks like is more than just an academic exercise for me.

What Jeremy says is,
Let’s be realistic here, you never have the perfect requirements. Your business partners with the vision will need to iterate and refine their vision, and the entire product team is better off if the development team is technically able to efficiently deliver features that weren’t even imagined at project inception. You can succeed with bad code, but all things being equal, I think you maximize your business’s chances of succeeding by taking software quality very seriously.
This is one of those things that is easy to overlook: change.  Especially unexpected change.  The "business people" don't know the difference between expected change and unexpected change.  Even "business people" who used to be really really smart technical people.  Once you're outside the code, you have no idea what magic is needed to make changes.  That's why these business people always come to you with this odd look on their face and ask, "Can we do this??"  Sometimes you look at them like they're crazy and say, "Duh."  But other times you blow up at them, "What?!  That wasn't in the original spec!"  That's why those business people have that funny look on their face, they never know what to expect.  Of course, that's also why some of these business people adopt the attitude of, "I don't want to hear about it, just get it done by tomorrow."
Let me be very clear here, I’m defining software quality as the structural qualities of code structure that enable a team to be productive within that codebase for an extended amount of time.
So that's why code quality is important.  The business people should want you to be writing quality code because it means you can respond to their changes with a good attitude and quick turn around time.  And you should want to be writing quality code because it means you can deal with those changes without going out of your mind, and without adding more and more hacks into your code.

Jeremy's blog post goes on to list some "qualities" of good code.  One of these I think is very important:
Feedback. I think the best way to be successful building software is to assume that everything you do is wrong. We need rapid feedback cycles to find and correct our inevitable mistakes.
He also has a list of links to his MSDN articles on various valuable patterns and principles which you can apply to help keep your code maintainable.

Monday, January 25, 2010

My TDD Struggle

I'm a huge fan of the concept of TDD (Test Driven Development).  I've done it a few times with varying success but I intend to make it a constant practice on anything new I write.  If you want to see people doing it right, go watch some videos at http://katacasts.com/.  Now on to the words!

TDD is the red/green/refactor process.  Write the test, watch it fail.  Go write the bare minimum of code possible to make it pass.  Refactor the code, and refactor the tests.  Repeat.

This process lends itself to what people call "emergent design."  This is the concept that you don't stress out trying to devise some all encompassing design before you begin coding.  You sit down, you write tests, and you let the design emerge from the process.  The reasoning here is that you'll end up with the simplest possible design that does exactly what you need and nothing more.

That point hits home very strongly for me because of my experience with both applications and code that have been over designed and end up causing all sorts of long term problems.  So the call for simplicity is one I am very eager to answer.

BUT.  Clearly you can't just close your eyes and code away and assume it will all work out.  There is an interesting tight rope walk happening here.  As you are coding you have to be constantly evaluating the design and refactoring to represent the solution in the simplest possible way.  But what TDD is really trying to get you to do is not think too much about what is coming next and instead pass the current test as though there wasn't going to be a next test.

It's that "ignoring" the future part that I really struggle with. The knee jerk negative reaction is that this will cost you time because you're constantly re-doing work.  There are times when this is probably true, but in general the tests lead you through the solution incrementally, affirming you're on the right track each step of the way.  And when you suddenly discover something that causes you to back track, you've got all the tests ready to back you up.

But there are a few things that I don't think this technique is good for.  One is "compact" algorithms, the other is large systems.  We'll take them one at a time.  I was recently practicing the Karate Chop Kata which is a binary search.  My testing process went like this:

  1. When array is null or empty it should return negative one
  2. When array has one item 
    1. it should return zero if item matches
    2. it should return negative one if item does not match
  3. When array has two items
    1. it should return zero if first item matches
    2. it should return one if second item matches
    3. it should return negative one if nothing matches
  4. When array has three items
    1. ...
Numbers 1-3 were all implemented in the straight forward way you would expect.  But when I get to #4, now I have to actually write the binary search algorithm.  So now I have to decide if I'm going to write it with a loop, with recursion, with some form of "slices", etc.  I also have to figure out what the terminating conditions are and verify that my indexes and increments are all correct.  In other words I have to do all the work after writing that one test.  

And worse, these tests are stupid.  What am I going to do, write a test for every array length and every matching index?  I re-factored the tests later to be a bit more generic and more specific to the edge cases of the algorithm in question.  If you'd like to see what I ended up with you can checkout the code on bitbucket.

In general, writing your tests with knowledge of the implementation you're writing is bad, bad, bad.  Like @mletterle reminded me of on twitter, tests should test the behavior of the code, not the implementation of the code.  Bob Martin just recently wrote a post that made the same kind of argument in regards to Mocks.  

Now don't get me wrong.  The tests are still valuable in this example, they're just not as useful in an "emergent design" kind of way.

Moving on, the second thing that the emergent design mindset isn't very good for is complex system design.  Systems that are complicated enough to warrant DDD (Domain Driven Design).  In this case you really want to step back and take a big picture view and do a real Domain Model.  The emergent design approach may lead to a design with fewer objects or something, but this may not be a good thing if you're interested in a design that excels at communication.

With these systems you'd do your Domain Driven Design, then drop into your TDD and allow it to "emergently" design the actual implementation code of your model.  You're kind of getting the best of both worlds this way.  But its important to recognize that TDD is still an important part of this, even though you didn't let it guide the ENTIRE design.

So TDD and emergent design might not be the answer in all circumstances.  But I still think that you'll find a strong place for it in even these circumstances.

Anybody in the blogosphere strongly disagree with this?  Or perhaps, dare I ask, agree?

Monday, January 11, 2010

SCM Trade-Offs

Source Control Management (SCM) is, on the surface, a very simple topic.  You put all your source code in one place, then you check in and check out from there.  Advanced systems support merging changes if two people edit the same file.  And there you go, SCM in a nut shell.

And if you are just one person, or a small team, that's probably where the story ends for you.  But with larger teams, or more complicated application environments SCM inevitably morphs into Application Lifecycle Management (ALM).  ALM covers topics from requirements, to architecture, to testing, and release management.

I have found that typically it is ALM requirements that end up introducing branching to your SCM.  Branching is another simple concept.  You make a copy of the source code which can later be "easily" merged back with the original.  Unfortunately branching is another area that quickly gets much more complicated than all that (which I've written about before, in a surprisingly humorous post if I may say so myself...).  As the number of branches increase the amount of work required to track them and merge between them increases.

So you will always find that there is a delicate trade-off that must be made when you introduce a branch.  Branches give you isolation, letting people work independently from each other.  There are tons of reasons why this can be helpful, some of which include:
  1. You can work without fear of breaking other people's work
  2. You can try "experimental" stuff which may never actually be finished
  3. You can work on parallel features and release one without releasing the others
  4. You can do new work while still enhancing an old release (ex: service pack releases)
But branches also introduce the need to integrate.  If everyone works on the same branch, every check in is an integration.  And these happen so frequently it's hard to even think of them as "integration."  But if you introduce long lived branches, integration can now be delayed indefinitely.  There are plenty of horror stories about companies which tried to delay integration to the very end of application development and then spent almost as long "integrating" as they spent "developing."

This is where Continuous Integration comes from.  The idea is that you want to integrate very often (at least once a day according to Fowler), and that you want integration to not just mean merging code, but also running tests to verify that the integration is successful.  The point is that you want to catch integration issues early.  The reasoning is the earlier you catch them the easier they will be to fix.  The longer you wait to fix them, the more things will have diverged, or be built on code that needs to change.  So integrate often.

And this is where we arrive at a problem I've been struggling with for quite some time.  On the one hand, I want isolation for all the reasons I've already mentioned.  And on the other hand I want to integrate continuously to avoid all the pitfalls mentioned.  But you can't have both.

Naturally I've tried to look at how other people tend to deal with this issue.  There seem to be two big picture approaches:
  1. "Centralized" in which everything starts integrated, and isolation must be purposefully added
  2. "Distributed" in which everything starts isolated, and integration is tightly controlled
All open source projects I've looked at are run very "distributed."  Anyone can download and update the code in their own sandbox.  But to actually get that code into the project you must submit patches, which the project leaders review and apply if they pass their standards.  This works well for Open Source projects because you can't let anybody waltz in and start changing your code.  You need control over what code is being added and modified, and you want it to all be reviewed and tested.

In contrast most company projects seem to be run "centralized."  Mostly I've found accounts of a main branch with release branches for past releases and maybe a few feature branches.  You can work code reviews into a process like this.  Some systems support preventing check ins without code reviews.  Other people just make it part of the "process."  But in general, people are trusted to be making the right changes in the right way, so the control required in OSS projects isn't as strictly needed here.  You trust your own employees.

I suppose I should mention quickly that my words "centralized" and "distributed" DO line up with the differences between Distributed and Centralized Source Control Systems (like Mercurial vs. Subversion), but you can still use a Centralized Source Control System and work in a "distributed" fashion by using patches.

There are lots of reasons why you might work one way or the other.  But I still have a hard time figuring out what's right for me.  This could be because my requirements are unusual.  I'm not sure why they would be, but I haven't found other people worrying about them.  This makes me think either my requirements are very special, or they're crazy and I'm missing something.

Briefly, here's what I'm dealing with.  I have a number of different people working on the same application, but they are all working on un-related or only loosely related features.  We have frequent and regular releases of the application being done.  We try to target features for the appropriate release, but its incredibly hard to know if a feature will really be "done" on time.  Features get pushed back when:
  1. They under go dramatic changes when it reaches completion and users try to put it through its paces
  2. The development takes longer than expected
  3. The developer gets pulled off and placed on another feature
  4. The feature gets put on hold for "business reasons"
If everyone is working on all this stuff in the "main" branch and integrating continuously, what do we do when one feature is not ready to release but the rest are?  The changes are all tangled up in the same branch now and there is no easy way to un-tangle them.

The only answer seems to be doing any "non-trivial" work in Feature Branches.

But feature branches pose whole challenges of their own!  If you're writing Mercurial, then feature branches are no problem.  If you're developing a website with a database then feature branches are a bit harder, because you have to create a new database and fill it with test data.  But if you're developing an enterprise application with a complicated database (which can't just be loaded with generated test data) that talks to other databases (with linked servers and service broker) and has a large number of supporting services many of which depend on OTHER 3rd party licensed services; then what?  In that case, creating the full application environment for each feature branch is actually impossible.  And creating a partial environment is certainly not easy.

But it is precisely because of all of this complexity that we want the isolation!  But the complexity makes the isolation difficult (if it's even possible, which I'm not sure of yet) and time consuming.  I love paradox!

Perhaps you're saying to yourself, "Maybe you wont be able to actually run the app and do everything it can do in your feature branch, but surely the code is written so all these things that depend on other things are nicely abstracted so that you WILL be able to run the unit tests!"  Um, no.  Sorry.  It pains me to admit it, but I'm afraid that isn't the case just yet.

So where does that leave me?  Well, I want to implement continuous integration to reduce the integration issues and make releasing easier, but I also want the flexibility to develop features independently so they don't prevent other features from being released, but my environment is so ridiculous that I can't figure out how to set it up so feature branches are fast and easy to create (and more importantly useful).

So, can you help me?  Do you have any of these problems?  Have you managed to mitigate any of these problems?  Am I missing something?

Saturday, January 9, 2010

Publish ClickOnce with Albacore and Rake

Rake is a great build system written on Ruby.  It uses the Ruby language to build a wonderfully simple Domain Specific Language (DSL) for writing build scripts.

If you look around a bit you'll find that people are using Rake for all kinds of things.  Even .NET projects use Rake, including Fluent NH and Machine.Specifications.

Albacore is a Ruby library for Rake which gives you a whole set of useful predefined tasks for doing common .NET tasks, like executing msbuild.

With Albacore, building a .NET solution is as simple as writing this rake script:
desc "Run a sample build using the MSBuildTask"
msbuildtask do |msb|
  msb.properties = {:configuration => :Debug}
  msb.targets [:Clean, :Build]
  msb.solution = "spec/support/TestSolution/TestSolution.sln"
end
You execute that by simply typing "rake msbuild" at the command prompt.

You can even use Rake and Albacore to automatically perform a ClickOnce Publish!  For my office, I'm hoping that this will be a VERY useful thing.  To set it up, get the ClickOnce publish working in Visual Studio first.  With that done, write a rake script like this:
desc "Publish ClickOnce"
msbuildtask("publish") do |msb|
  msb.properties = {
    "configuration" => "Release",
    "PublishDir" => "C:/temp/",
    "PublishUrl" => "C:/temp/",
    "InstallUrl" => "C:/temp/"
  }
  msb.targets [:Publish]
  msb.solution = "slnFile.sln"
end

There are a few important things you have to get right for this to work.  First, you have to specify the PublishDir parameter or it wont copy your files to the PublishUrl.  Visual Studio makes this work automatically, but you have to do it manually if you want msbuild to do it.

The second thing to note is the use of forward slashes in the paths.  If you use backslashes you have to double escape them, once for Ruby, and once for cmd.  I have no idea why cmd needs the backslashes escaped, but that's the behavior I ran into and it's simpler to just use forward slashes.

With this all setup, you can run "rake publish" at the command line and your app will be ClickOnce deployed automatically.  You can also easily setup different ClickOnce deployments if you need to (ex: Test vs Production).

If you have any build steps at all that you think could be automated I highly recommend you check out Rake and Albacore.

Monday, January 4, 2010

Snow Blower Efficiency

Hi there, I'm a big nerd, and I'd like to prove it to you.

We've been getting a lot of snow in Cleveland, especially in the city where I live.  I use a snow blower to clear my drive way, and naturally I think about what the most efficient way to clear the drive way is while I'm out there in the cold doing it.

The solution I've come up with is somewhat interesting, so I figured I'd share.

There are a few factors to consider:
  1. Length of driveway
  2. Width of driveway
  3. Number of turns you make
  4. Number of turns of the thrower you make (the direction the snow is being thrown)
#1 and #2 are fixed, and there is nothing I can do (aside from buying a larger snow blower) to change those.  So the number of passes I have to make to clear the driveway is fixed.

Clearly, I'm going to go up and down the drive way, not side to side, as that will reduce the number of turns.  Given that, the number of turns I'm going to make is pretty much fixed.  Thus, the only other factor left for me to consider is the number of turns of the thrower I have to make.  As it "turns out" (har har), I actually can do something about this.  In fact, if I do it right, I shouldn't have to re-direct the thrower at all the entire time I'm clearing the drive way.

Here's two diagrams to help explain.  In the first diagram, I'm starting at the left top of the driveway and going up and down to the right.  In the second diagram, I'm starting in the middle and going down on the left and up on the right.



Notice that in the first image every time you turn, you have to also turn the thrower.  But in the second image the thrower is ALWAYS pointing to the right.  The downside to the pattern on the right is that your turns are wider, but I've actually found this is a good thing.  It's easier for me to make a wide turns than a sharp turn.

The last question is why start in the middle?  The reason is that when you're in the middle, the snow has to be thrown the farthest, and sometimes because of the wind or whatever it doesn't quite make it fully off the driveway.  By starting in the middle you make sure you never throw snow over ground you already cleared!

And with that, I have to go snow blow the driveway...  again.

Tuesday, December 22, 2009

People Problems

I'm sorry to have to tell you this, but your job is to solve problems for people.

I don't even have to know what your job is, and I can still say that with a pretty high level of confidence.  Are you an engineer building bridges?  You're solving a problem for people who need to get across that divide.  Are you a cashier at the grocery store?  You're solving a problem for people who need to pay for their groceries (and for people who need to take money from people for groceries, double whammy).  And of course, are you a computer programmer?  You're solving SOME, maybe not very well specified, problem for your users.

It really doesn't matter how far removed from people you are, you're still solving problems for people.  You could be completely devoted to the inner most workings of the Windows kernel.  You're actually worse off!  You're solving problems for users who want to check their email, and programmers who want to write MS Word, and designers who want to make Windows look pretty, and marketers who want to sell Windows as the most stable ever, and finance people who want to show market growth, and the list just goes on and on and on...

Sometimes you are aware that you are solving problems for people, but maybe you don't really know what problem you're solving.  Like the grocery store clerk who is really nice and friendly and makes all the customers happy going through the line.  Maybe they think their job is to make you happy, but it's not.  The problem you want them to solve is to figure out how much money you owe, and take it from you.  And you want them to do it quickly.  If they can do that AND make you happy, then they are a very good grocery clerk.  If they only make you happy, then they just aren't very good.

A similar thing happens with programmers.  I frequently get confused and think that my job is to make high quality software and write high quality code and do good high quality design work.  But its not.  My job is to solve some problem my client has.  As long as I fix their problem, I've done my job.  Maybe I could have fixed their problem better with beautiful code I'd be proud to hang on my wall at home.  That would be a bonus.  But all I'm supposed to do is solve their problem.

That is, unless I'm actually supposed to be developing a long life product, which will require all kinds of future enhancement and maintenance and re-configuring.  In that case my job is to both solve the client's problem AND develop a strong software product.  These are two competing goals.

And that's the thing about People Problems:
  • They are never clear cut
  • They tend to overlap
  • They always involve trade-offs
They're not clear cut because frequently you don't know what problem your supposed to be solving.  Or there are a bunch of problems you're supposed to be solving and you don't know which is most important.  Or different people have different problems and you need to simultaneously solve them all.  Create an app for a user!  Create it in the time your managers wants!  Make the app a platform to build a product on for your boss!

And this is where the trade-offs start.  You simply can't HAVE your cake AND eat it.  See?  Once you EAT it, you don't HAVE it anymore.  Or if you HAVE it, then you haven't EATEN it.  See?  I just thought that up. Pretty good huh?

The "real world" is all about People Problems.  And People Problems inevitably lead to trade offs. And trade offs inevitably lead to disappointment.  For example, if you choose to make the code super high quality, you wont be disappointed, but your boss will be because of how much it cost.

The trick is to understand that above all you are solving people's problems.  Then understand that necessarily involves trade offs.  Then try to take a big picture view when deciding on how to make those trade offs.  Hopefully that will at least help you deal with the inevitable disappointment.  At least you'll know you made the best decision you could for the specific People Problem you were faced with.

Of course, you'll probably be disappointed when you find out later that you didn't have all the facts straight and your decision was based on faulty information or just information that has since changed.  But that's a whole different dimension of dealing with People Problems.

Tuesday, December 15, 2009

WPF UserControl IsEnabled in WinForms host

While debugging today, I ran into something rather odd.  Two things actually.  And since I'm falling behind in my posting I thought I'd share.

Here's what I was dealing with.  I have a WinForms UserControl which contains a WPF UserControl within an ElementHost.  The WPF control is being informed of what is selected on the form and is Enabling or Disabling itself accordingly.  However, there is a special case in which the form knows it wants the control to be disabled all the time.

Before I go any further.  If you're working with WPF controls hosted in WinForms and you're dealing with enabling and disabling things, you should be aware of this bug and this workaround on Microsoft Support.  It will cause all kinds of havoc if you set things to Enabled=false before showing them.

The WPF user control is using MVVM, so it's IsEnabled property was bound to an IsEnabled property on the View-Model.  This is where we run into the first interesting thing: this doesn't work.  The vm.IsEnabled property was changed, and the PropertyChanged event was fired with "IsEnabled" as the property name, but the WPF user control's IsEnabled property did not change.  I found someone else who had this same issue and posted about it on this blog.  His work around cracks me up, I can't believe it works...  WPF is crazy.

My work around was to just hook the PropertyChanged event myself like this:
void _vm_PropertyChanged( object sender, PropertyChangedEventArgs e )
{
  if ( e.PropertyName == "IsEnabled" )
    this.IsEnabled = _vm.IsEnabled;
}
I was stunned when this code didn't work. It fired, it set the property, but after setting it the property value didn't change. And it didn't change after WPF got a chance to run through a layout pass either.

This is the second interesting thing.  Turns out the WinForm's control that the WPF control was in was disabled. Why?  Because the parent form had disabled it due to that "special case" I mentioned.  So when I set the WPF user control's IsEnabled to true it didn't matter because it's parent's Enabled property was false. So it just shrugged it's shoulders and ignored me.

So before I can enable the WPF control, I need to enable it's parent, the WinForms control.

In order to get this whole mess working what I ended up doing looks something like this:
  1. View-Model fires change event for IsEnabled
  2. WPF User Control fires custom change event for IsEnabled (it does NOT try to set IsEnabled)
  3. WinForms User Control sets Enabled = CustomEnabled from WPF User Control
  4. WinForms User Control's EnabledChanged fires
  5. WinForms User Control sets WPF UserControl's IsEnabled property = this.Enabled
  6. WPF User Control's IsEnabledChanged fires
  7. WPF User Control sets View-Model's IsEnabled = this.IsEnabled
This ensures that all Enabled properties on all the objects involved here will always be in sync, no matter which one you change.

Part of the problem here I'm going to blame on bad design.  I don't think the control should be being enabled and disabled in two completely different ways (one from the top (WinForms), and one from the bottom (View-Model)).  The rest of the problem I'm going to blame on Enabled properties being really confusing.  They have mystical relationships with their parents and their values can change at different times.  Most properties when you give them a value either have that value after the set, or throw an exception.  But not Enabled!  It's mystical.  I find that I know this but that I still get bit by it when I'm not expecting it.

Wednesday, December 2, 2009

Usability: Locking Doors

Reading The Design of Everyday Things has caused me to start paying attention to usability issues I run into in day to day life. Some of them are interesting and I'm going to try to remember to share those here.

This one is about doors. DOET talks a lot about doors. The specific part I want to talk about is how they lock. A normal door works something like this:
  • Use the lock mechanism to lock the door
  • When locked the door cannot be opened
  • Use the lock mechanism to unlock the door
  • When unlocked the door can be opened
A while back I encountered a door that worked differently than this though. Unlike the normal door, which when locked can not be opened, this door could still be opened from the inside even when it was locked without unlocking it! But it could not be opened from the outside when it was locked.

You can see where the designers were coming from here. The point of locking the door isn't to keep people inside locked in. The point is to keep people outside from getting in. Letting you open the door from inside even when it's locked aligns more closely with the purpose of locking the door. And you can imagine all kinds of situations where this would be nice: answering the door when someone knocks, opening the door to leave the house, etc.

So this change seems to be a great idea: it fits the purpose more closely, and it eliminates some small annoyances. Unfortunately it introduces a really big annoyance of its own: its super easy to lock yourself out.

All you have to do to lock yourself out of the house is walk out and close the door behind you.

Preventing you from locking yourself out of the house isn't one of the stated purposes of a normal door, but because of how it works it manages it all the same.

But lets look at how a person uses the door the way a software engineer looks at a person using software, in terms of "clicks". Lets assume the door is already locked and a person wants to leave the house and leave the door locked behind them.

With a normal door:
  1. Unlock the door
  2. Open the door
  3. Close the door behind you
  4. Lock the door
With the special open-while-locked door:
  1. Open the door
  2. Close the door behind you
Which of these doors is better designed?

Monday, November 23, 2009

Don't Write Another Line Of Code Unless...

Don't write another line of code unless you know and have been influenced by the following things:

SOLID (from Uncle Bob)
SRP* - Single Responsibility Principle
Every class should have one clear and well defined responsibility
OCP* - Open Closed Principle (from MSDN)
Extend the behavior of a class without modifying that class
LSP - Liskov Substitution Principle
Derived classes must be substitutable for each other (this one is kind of obvious, but still important)
ISP - Interface Segregation Principle
Make fine grained interfaces, not fat interfaces (this goes along well with DIP)
DIP* - Dependency Inversion Principle
Classes define their dependencies, which other classes implement

* The three I've starred I believe are the most important as they make the biggest difference in fighting spaghetti code.

YAGNI (from Wikipedia) - You Ain't Gonna Need It
This is an Extreme Programming concept which basically says you shouldn't add functionality until you actually need it

TDD (from Wikipedia)- Test Driven Development

Loose Coupling/High Cohesion (from MSDN)

Code Smells (from Fowler)
A code smell is a "surface indication" that there may be a deeper problem with your code.  It is very useful to know these, especially when practicing TDD.

Basic Design Patterns - Singleton, Observer, Mediator, Strategy, Decorator, etc
There are lots of books on the major design patterns. I personally haven't read this one, but it has been highly recommended to me: Head First Design Patterns

MVC/MVP/MVVM (from Fowler) - Model View {Controller|Presenter|View-Model}
The biggest piece to take away from this, in my opinion, is the responsibility of the Model and the separation of the UI (the view) from the Application layer (the Controller, Presenter, View-Model).

DI/IoC/Service Locator (from Fowler) - Dependency Injection/Inversion of Control/Service Locator

Law of Demeter (from Wikipedia)
This is a useful concept to be aware of, but one that really shouldn't be thought of as a law. See what Phil Haack has to say.

Database Isolation Levels (from MSDN)
Anyone doing anything with databases needs to know the Isolation Levels, what they do, and when to use them.

Concurrency Models - Optimistic, Pessimistic (from Fowler's Patterns of Enterprise Application Architecture)
You can't write any multi-user application that updates data without understanding concurrency and the various patterns for dealing with it.

Version Control (from Wikipedia)
You should be familiar with centralized version control (like Subversion). And I think you should also understand distributed version control (like Mercurial).

--
You don't have to be an expert in all these things. But any decent developer should have at least a basic understanding of these concepts and be able to understand what they are when someone else mentions one.

Our industry is REALLY weak on education. We go to school and learn about data structures, semaphores, virtual memory, file systems, etc. Then we graduate, get jobs in Software Engineering and promptly never use any of that. I'm not saying it's not useful stuff to know; it is useful to know. But its not what you deal with day to day as a software engineer.

You can't be a software engineer without knowing the stuff on this list. I'm serious. If you don't know it, you're just a dude who's hacking out code.

That said, I'm pretty sure I'm just a dude who's hacking out code... What things do you think I should have on this list before I write another line of code?

PS. There are also lots of good books you should probably read if you're thinking about being, or already are, a software engineer.

UPDATES:
1/28/2010: added Code Smells and re-ordered list

Tuesday, November 10, 2009

DDD is Not About Perfection

The main practice of DDD (Domain Driven Design) is refactoring to deeper insight. The idea is very similar to much of what the Agile practices preach. Namely, when you find you have
  1. misunderstood something or made a mistake
  2. been given bad information
  3. learned something new that changes previous assumptions
You go back and you update your code to reflect your new understanding. In Agile, this is called embracing change, in DDD its refactoring to deeper insight.

This is one of those principles that seems like it shouldn't need to be said. If someone knows that what they've done isn't right anymore who WOULDN'T go back and fix it?! But it turns out this is one place where real life and theory don't line up. The thinking usually goes something like this:
We've spent a lot of time working on this feature, we're out of budget, it works fine in 90% of the cases, and we can just add this little hack that will take care of the other 10%. Therefore it makes more sense for us to just do the little hack.
I'm sure you've seen this line of thinking before, so you're already anticipating that I'm going to say this is stupid. But hold on. Its not stupid. This is actually totally sensible thinking, but there are two problems:
  1. You made up that thing about "90% of the cases." You actually have no idea how often the "edge cases" that are a problem for you will crop up. And for all you know, those may be the more important cases, which your system can now only accommodate with a weird hack.
  2. You haven't considered changes that might arise in the future, or insights you may have in the future. If any do crop up that are related to the "10%" edge cases, you're now going to be forced to build hacks on top of hacks (on top of hacks, on top of hacks, on top of hacks...).
So obviously you should never write the hack, you should always embrace the change and refactor to deeper insight.

Nope, sorry, wrong again. Unfortunately we are here living in the real world. We have real world constraints: Time and Money. If we always took the time to fix everything we discovered we got slightly wrong we would never deliver a product, ever. And shipping is a feature.

So... sometimes we're going to have to hack, which might get us into a world of trouble? And sometimes we're going to have to blow our budget refactoring? How do we know when to do which?

In Strategic Design - Responsibility Traps Eric Evans (the founder of DDD) says "the whole system will not be well designed." This is an inescapable fact if you're working on a large complex system. If you're working on a small simple system, maybe you can pull it off, but even then I doubt it.

How can the guy who's whole development technique revolves around refactoring to deeper insight say the whole system will not be well designed? Well, he has an answer of sorts. Evans says that what you need to do is identify your application's Core Domain. What is it that your application does that sets it apart, makes it important, or provides the most value for the users? That's your Core Domain. Now if a change crops up in the Core Domain, you refactor to deeper insight. This is the most important part of your app! It's the part you'll be building on for everything else in your app. This is the part of your app has to be perfectly designed.

But what about parts that are NOT the Core Domain? Or what if it's not so easy to define your app's Core Domain? Then what do you do? Well, you weigh the options, and take your best guess.
  • Is there time in the budget?
  • How hard will it be to refactor to account for this change?
  • How much better will the app be if you do change it (time saved? # people affected? usability? performance? correctness?)?
  • Can you convince yourself it is unlikely other changes will have to be made in the future that will be related to this change?
Once you have answers to these questions that are as accurate as you can manage, then you have to just guess. Because your answers to these questions are NOT scientific. And you have no way to predict the future. But you have to try anyway, so you guess.

If you think it's going to be very hard to accommodate the change and you think the change wont make your app all that much better, then hack it. If that's reversed, refactor it.

I'm a programmer, and I'm hungry for perfection, so I always lean toward wanting to refactor it. I think refactoring to make it correct anytime you have the time and ability is the right move. You'll end up with an app you're proud of, that works better for your users, and is easier to maintain and update. But we have to face facts! Sometimes the cost is simply too high. Sometimes we're forced to hack it now, and pay the consequences later.

The good news is that DDD helps tremendously with this. If you can define a Core Domain, you're that much better off because you have now decided what your application is all about. This will help you in every decision you need to make.

Further more, DDD is drastically easier to refactor and maintain than spaghetti code. So the cost of refactoring to deeper insight is lowered when you're writing DDD.

But in the end, we have to realize that DDD is not about writing perfect code. Its about writing good code, that makes the complexity of your application manageable. But we know that despite all the benefits DDD can bring, it doesn't promise perfection. The simple truth is that software is very very hard to write, and designing enterprise applications is even harder. So the best we can do is write Good Enough software, like they say in The Pragmatic Programmer. But hopefully DDD will help us to raise the bar on how good that software is.

Monday, November 2, 2009

Knowledge in the Head and in the World

A looooooooong time ago I wrote a post called Theory of Software Usability.  This post was primarily about the tradeoff between “Ease of Learning” and “Ease of Use.”

I used my favorite example of Vim vs. Notepad.  Vim is an advanced modal editor that a n00b wont even be able to get text into if they don’t know what they’re doing.  Whereas Notepad is just about the simplest application you can imagine that anyone can figure out how to use.

My argument was that Vim is extremely usable but difficult to learn while Notepad is extremely learnable, but not really all that usable.  So there is an implicit tradeoff between Learnability and Usability. 

Recently I have been reading The Design of Everyday Things and I can across a concept that is an interesting corollary to the Usability vs. Learnability issue.  The book presents “The Tradeoff between Knowledge in the World and in the Head”.  Knowledge in the world is simply information that is readily available in the world, so you don’t have to learn it, or at least you don’t have to learn too much.  In The Design of Everyday Things an example of a typist is used. 

“Many typists have not memorized the keyboard.  Usually each letter is labeled, so nontypists can hunt and peck letter by letter, relying on knowledge in the world and minimizing the time required for learning.  The problem is that such typing is slow and difficult… But as long as the typist needs to watch the keyboard, the speed is limited.

If a person needs to type large amounts of material regularly, further investment is worthwhile: a course, a book, or an interactive computer program… It takes several hours to learn the system and several months to become expert.  But the payoff of all this effort is increased typing speed, increased accuracy, and decreased mental load and effort at the time of typing.”

At the end the book presents some tradeoffs between knowledge in the head and in the world in terms of 5 properties, retrievability, learning, efficiency of use, ease of use at first encounter, and aesthetics.  It breaks down like this, knowledge in the world is retrievable, requires little to no learning, is not efficient, is easy to use at first encounter, and can be unaesthetic and inelegant.  On the other hand, knowledge in the head is not retrievable, requires lots of learning, is efficient, is not easy at first encounter, and can lead to better aesthetics.  So basically, they are at odds with each other.

Bringing back my Vim vs Notepad example, we can see how this fits right in.  Notepad puts all the knowledge you need “in the world.” All the labeled keys on your keyboard do exactly what you’d expect and the other functions are clearly labeled in the menus.  In Vim on the other hand, you can’t even enter text until you learn the “i” command.  The knowledge must be in your head.  All the tradeoffs listed above apply perfectly to this example.

I think this is a very important concept to keep in mind when doing software design.  Who is your user?  What job are they doing?  Often often will they be doing that job?  Will new people need to figure it out on the fly, or will the same people always do it over and over again?  The answers to these questions will help you decide if you should emphasize knowledge in the world or knowledge in the head.  If you are building a public facing website that many people will visit, you want to emphasize knowledge in the world.  If you are building an application for something like data entry you may want to emphasize knowledge in the head.

The important thing to take away from this is that there is a tradeoff and you have to make a decision one way or the other.  Knowledge in the world is not always better than knowledge in the head, and vice versa.  Pay attention to what you are building and who you are building it for and design accordingly.

Tuesday, October 20, 2009

Intangible Value

Rory Sutherland is a marketer who recently gave a TED talk. The talk is about 16 minutes long and is hilarious, you should totally watch it.


He opens the talk with this gem, "if you want to live in a world in the future where there are fewer material goods, you can either live in a world which is poorer (which people generally don't like), or you can live in a world where actually intangible value constitutes a greater part of overall value."

Seth Godin is another marketer who has a short and sweet blog post called Creating sustainable competitive advantage in which he argues that competitive advantage rarely comes from proprietary technology or technological barrier to entry. In other words, technology alone will not allow a business to succeed because its competitors will quickly be able to copy the technology.

He has a list of things you can do to gain competitive advantage, 3 of which apply here:
  • You can build a network (which can take many forms--natural monopolies are organizations where the market is better off when there's only one of you).
  • You can build a brand (shorthand for relationships, beliefs, trust, permission and word of mouth).
  • You can create a constantly innovating organization where extraordinary employees thrive.
Tying in with Sutherland, these are about adding intangible value. You can gain intangible value by building a network around your product, or by building trust and a name for yourself ("brand"), or by being a constantly innovating organization.

The last is half intangible, half tangible. The actual innovations produced are tangible, but being innovative adds its own intangible value, both to your customers as well as your own employees and even to job applicants! Emphasizing extraordinary employees is a relatively intangible thing which can produce tangible benefits across the board (better products, faster delivery, lower employee turn over rate, and better employees). Thus the competitive advantage.

I think this concept of Intangible Value can be extended into software itself. Possibly the best example is usability. Some software usability concerns are tangible: how long does it take someone to accomplish a task, how many clicks are required, etc. But other usability concerns are intangible: does the user enjoy using the software or does it make them want to shoot themselves in the face.

Seth Godin's post talks about things you can do today to gain competitive advantage, but Rory Sutherland's talk is about how we as a people need to learn to value intangible things more. This is much harder than it sounds.

When you're evaluating two products, you look at the feature lists. If one product has more features, you're likely to decide that it is the better product. But while it may have more features, it may also make people want to shoot themselves in the face. Can we include that on the list of features?

As an example, compare Microsoft Visio to Balsamiq Mockups. Visio is a very full featured product which is ridiculously flexible and powerful compared to Balsamiq. But everyone I know likes Balsamiq better. Why? It's the shoot myself in the face factor. Balsamiq is faster and easier to use. In fact, it's a joy to work with. That is a relatively intangible benefit, but it's real.

As another example, take 37 signals. I have not personally used their products, but I know from what I've heard and from what they've said that their focus as a company is on building slim lined and usable software. There are big box alternatives to their products that have been around for much longer and are far more "configurable," but people love 37 signals. Again, for mostly intangible reasons I think.

So intangible value is a real thing which is often overlooked by the "deciders" but always appreciated by the users. The challenge for those of us who design software is to figure out how to add that intangible value into our products, and how to make potential users aware of it. The challenge for people in general is to recognize intangible value when they come across it and not dismiss it as unimportant.

Wednesday, October 14, 2009

What a Programmer Wants in a Manager

Management is an oddly fascinating subject. It's kind of dirty word these days, but when you distill out all the nonsense and get down to what it's really about, it's interesting. Managing programmers, or "knowledge workers," is, in many ways, a special case and requires special consideration. This is because you can't break a programmer's job into a series of reproducible steps. Programming is an inherently creative job, which is why it's often compared to craftsmanship.

In thinking about how to manage programmers, I tend to empathize with the programmers more than the managers. The way I see it, a programming shop's number one expense AND number one asset is its programmers. So it seems pretty clear to me that you aught to do everything you possible can to keep those programmers working well. The challenge is of course figuring out how you actually do this.

The book First, Break All the Rules, suggests that a manager's job is to discover the talents of his people and direct those talents to the business's goals. I like looking at it this way because it indicates that the manager should recognize what his people are good at, and then let them go be good at it. The trick then is to make sure the things they're being good at are also the things the business needs to be good at.

Joel Spolsky goes even further and says that a manager's "most important job is to run around the room, moving the furniture out of the way, so people can concentrate on their work." At least, he says that's how managers at Microsoft behaved. Again, there is a large focus on getting out of the way so your people can work.

Recently Fog Creek announced a series of training videos they are selling. The video series is $2000 and a little conceited if you ask me... But in the promo video, one of the Fog Creek dudes says, "Developers are assumed to know the right answer. So you don't start from a position of negotiating about whether or not you could possibly have the right answer. You assume they have the right answer and that's there job to explain to you why its the best solution, not why its the wrong solution or the right solution." In this we're seeing some of that "get out of the way" mentality but also a certain amount of built in trust.

I have my own theory on the best way a manager should behave, which is strongly influenced by these references as well as just about every word in Peopleware. I think it breaks down like this:
  1. Trust your people
  2. Value your people's time over just about everything
When I say trust, I'm not talking about blind trust. I'm not a complete idiot! But I am talking about a change in tone. A manager needs to set the goals and objectives people are working toward, and a manager needs to ensure those goals and objectives are being met correctly and effectively. But a manager should trust their people to do the work right and in the best way possible. As a manager, you can ask for proof of why what people are doing is the BEST way. But you need to be careful that you don't demand proof they are not completely wrong. There is a subtle difference here which has a huge effect on morale.

I think this is very important. Programmers want to be treated like experts. They want their opinions to matter. If you stifle that, you will end up with frustrated programmers, and frustrated programmers don't work as well. Worse, since programming is a creative activity, if you're actually stifling creativity you're ruining your product. The best way to improve morale and encourage creativity is to offer up some trust and treat people like adults.

If your people know that they are trusted, and that their ideas will be seriously considered, they're more likely to bring ideas to you. They're more likely to think outside the box. These can only be good things. If instead they feel untrusted and are afraid their ideas will always be shot down, they wont bring anything to you.

Programming can be detailed tedious work. Nothing pisses a programmer off more than the impression that the time and effort they have spent was wasted or simply unappreciated. This is why programmers hate dropping a project in the middle to work on something "new" and "higher priority" that "just came up." New higher priority things DO come up at the last minute. But if a manager just tosses it on a programmer's desk and says, "get this done first" they're not valuing the programmers time.

I firmly believe a manager's job is to push the furniture out of the way so the programmers can get their work done. But, we're not really talking about furniture. We're talking about all the complexity of a project. The inter-relations between different teams, the ever changing client demands, the relative priorities of different assignments. These are things the managers should be focused on working out so that programmers don't have to spend so much time worrying about them.

Again, much of this is just tone. When a manager is laying out the work that needs to be done and the order it needs to be done in, and who needs to do what work when... they can treat this as a power opportunity for themselves. To hand out assignments from on high with little regard for explaining the circumstances to the programmers and a simple expectation that the programmers should take it and get it done. Or they can treat this as an opportunity to indicate that the goal is to optimize the developers time so they can focus and do their best work instead of dealing with the sticky details of the real world that programmers simply don't like.

A manager has to do the same work either way. In the end, much of management really comes down to politics. And since I believe the programmers are the most important asset going for a business, I believe the politics should be oriented around keeping the programmer's morale high, avoiding frustration as much as possible, and engendering a corporate culture where the programmers feel their work is valued and important.

Thursday, October 8, 2009

Responsibility Traps

Over at InfoQ there is a presentation by Eric Evans called Strategic Design - Responsibility Traps. This presentation is full of all sorts of gems like "one irresponsible programmer can keep any 5 top notch programmers busy."

His presentation is all about how to take legacy systems and apply DDD (Domain Driven Design) to them when doing new development. In the process he addresses lots of really important issues like, "the whole system will not be well designed," which I may dedicate a whole post to in the future.

What I want to mention here is what he calls Responsibility Traps. These are traps that responsible programmers (read: good programmers) fall into. In the presentation he mentions two:
  1. Building a platform to make others productive
  2. Cleaning up other people's mess
The reason why these are traps is that "you are not the one who finally delivers the sexy new capability." Instead, what you've done is "made the irresponsible programmers look even better". Ultimately Evans believes this leads to this fact: "Because the best programmers are busy making the platform strong, the actual delivery of the Core Domain is being done by irresponsible programmers."

I had never really thought about this, but I think he's dead on. Your real star players, over time, gravitate to working on more abstract projects like frameworks and platforms and very technology oriented things. This migration makes sense on the surface, because these things are harder, so you want your best people working on them.

The problem with this is that these are not the projects that make the biggest difference to the product as a whole. These things are not part of the Core Domain. They may be important. In fact they may be absolutely essential, but it doesn't change the fact they are not the MOST important. They are not what your application is all about. So what happens is your irresponsible developers end up working on the MOST important parts of the application.

Evans consistently uses the word "irresponsible" instead of "bad" or "weak". I think this is more than a political move on his part. The reason why it's a problem that the irresponsible developers are writing the core domain is that they write it irresponsibly, not that they write it badly. What does that mean?
  • They hack through it
  • They leave it a mess
  • They don't question the design when it stops working well
  • They keep bolting new stuff on top instead of refactoring
  • They introduce performance and maintenance problems
These things are "bad", but for the most part they are not outwardly noticeable. Irresponsible developers may be fully capable of delivering a project with few to no bugs that looks just like what the business people asked for. But because they wrote it irresponsibly it will be a thorn in the side of the project from then on. Unfortunately, the business people wont know that. And if the responsible people tell them, the business people either a) wont believe them or b) wont understand the severity.

There is a certain amount of "the sky is falling!" here. The responsible people say there is a problem in something that has been written. The business people say, ok, go fix it. The responsible people toil away for awhile and return with the issues resolved. The business people don't see a difference, usually there ISN'T an immediate noticeable difference. So it looks like these responsible people keep shouting about the falling sky and then spinning their wheels on nothing for weeks, while the irresponsible people are off getting things done (and creating more problems).

The point Evans is trying to make with this is that the responsible developers are actually being somewhat irresponsible by allowing this to happen. This isn't about being political and trying to make yourself look good. I mean, it's partly about that. But it's really about being truly responsible and embracing the fact that the whole system will not be perfect and focusing on making the most important parts be the parts that are the highest quality. Those are the parts the responsible people should be working on, those are the parts YOU should be working on!

Monday, October 5, 2009

Reading List

Most "technology" books aren't very good.  They tend to just be focused on a specific version of a specific technology.  A book like this can be useful when you're first starting out, but after you read it, you'll never pick it up again.  However, there is another class of programming book that doesn't fall into this specific technology category.  Books of this other class are timeless in nature because they deal with the actual art of programming instead of specific syntax or frameworks or tools.  These are very valuable because they have the ability to dramatically expand your programming horizons and make you a much better developer.

This reading list will only contain books that I feel have a certain timeless quality to them and are mostly independent of language or framework.  I've prioritized this list in order of how influential the book has been for me.

The Art of Programming

Clean Code - Bob Martin
This book is about code.  It's not about what that code does, or code patterns to accomplish things, or code architectures to organize things.  It is just about code and how to write it so it is clean, understandable, and maintainable.  It is likely the single most important book I've ever read about code because it applies to every line of code I write.

Practical Object-Oriented Design in Ruby - Sandi Metz
This book is in Ruby, and it's about Ruby, but it's also the best treatment of OO practices I've ever read.  And those practices are easily applicable to other OO languages, including static languages like C#.  This book has done more to develop the way I approach building OO code than any other resource.


If you've ever read the "Gang of Four" patterns book, or any books that repackaged those patterns you know what a Design Pattern is all about and you're probably bored with them. The patterns in this book are so much more influential and important than the GoF patterns, so don't let the word "patterns" scare you off. Think of this book as the text book for anyone developing multi-user "business" web apps or rich clients. It covers nearly ever major problem you are likely to be faced with if you're building from scratch.  And if you're using a framework, it will explain the patterns used by that framework and their trade-offs.


Growing Object-Oriented Software, Guided by Tests - Steve Freeman and Nat Pryce
This book's approach to building a large application is deeply important.  It covers outside-in development, the importance of TDD, and many useful OO and testing patterns as well.  Skip the part that goes step by step through code, just read the first and last parts.  (The RSpec Book actually does a better job of describing outside-in development, but it's much more tech specific.)

This is the most comprehensive book on enterprise application development I've ever encountered. For me it was a complete game changer. The book itself presents you with concepts and examples and patterns, but it doesn't get bogged down with implementation issues. The result is after reading it you know you HAVE to start writing code this way, but you really don't know how to write it just yet. I no longer actually practice the strict rules of DDD, but the language and patterns of this book still strongly influence by approach to developing complex domain code.

This book wont give you dramatic new ways to write code. Instead it will give you dramatic new ways to think about code and your responsibilities as someone who writes code. It includes what to my mind is the beginnings of Agile Programming and many of the SOLID design principles. It is also packed with parables that seem obvious until you realize they've happened to you at work. It should be required reading for any developer.

Managing Programmers

Peopleware: Productive Projects and Teams (Second Edition) - Tom DeMarco and Timothy Lister

This book is some interesting cross between a book for managers and a book for programmers. Its a great read and is likely one of the most influential books in our industry. It has clearly defined much of the culture of companies like Fog Creek and Microsoft and even Google. You should read it, but if you don't work for one of those companies be warned you might get a little depressed.

First, Break All the Rules: What the World's Greatest Managers Do Differently

If you are in any kind of "Management" role you should absolutely read this book. If you're not, you should still read this book, cause it will help you manage your manager. Even if management doesn't directly affect you at work, you still should read this book, simply because it's interesting and will give you new outlook on all the places you spend money. There is nothing specific about programming in this book, just a really solid and entertaining book on the result of a giant Gallup poll on managers.

Software Development Related


This book is short and a ridiculously fast read. The content is so common sense you might trick yourself into thinking you already knew it. And the truth is you probably DID, but you hadn't thought about it consciously. And for that reason alone, this book is worth reading. I think the most valuable thing about this book is it shows you that you can work on Usability without spending a fortune on a usability lab or outside consultants or long term studies with thousands of volunteers.


UPDATE 5/2/2013: added POODR, reordered list.