Wednesday, April 29, 2009

Management decisions for good developer cost-benefit ratios

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/management_decisions_for_good_developer_costbenefit_ratios.htm]

I've often seen development groups (or their managers) dismiss a good idea with "we can't afford it." The irony is that the group is already "affording" other expenses - developer salaries, MSDN licenses, hardware, and office space - so the question really becomes not "are there funds", but rather "what is the best way to spend our funds". There are at least three common examples where, for some reason, many managers shun the best cost-benefit ratio.

Problem 1: "We cannot afford a star developer - let's get two average developers instead."

The irony is that one star developer is far more profitable than two average developers. The star will build complex things that a dozen average developers will never be able to dream of. The star will write more solid code that spares you costly production errors. The star will solve the same problems faster by leveraging advanced techniques (like code generation, refactoring, or just elegant solutions). So, if you're creating a team of more than 10 developers, exchanging the bottom two spots for 1 star is a good investment. ThoughtWorks, a world-class consulting firm, does a good job of demonstrating the profitability of this business model.

Problem 2: "We cannot afford that tool - just do it another way instead."

Say you spend somewhere between $70K-$120K on an average developer (not just salary, but benefits, payroll taxes, etc...).  Let's use $100K for easy numbers. At 50 work-weeks (assume 2 weeks of vacation), that's $2000 a week to pay for a developer - i.e. $50 an hour. So, a $50 tool that saves your developer one hour a year is a break-even investment.

Now about the "power tools" out there - like CodeSmith (for code generation), or ReSharper (for refactoring), or Simian (for detecting code duplication), or NDepend (for code metrics) - say it's a few hundred per tool (i.e. less than 0.5% of your developer labor cost). However, a tool like CodeSmith fundamentally changes the rules of the game, and can save a development team hundreds of hours. Sure, you can try to find open-source alternatives to each of these, and if you find something that fills the niche you need - great. A similar problem applies to hardware (where's there's not an open-source alternative)- for example when management "saves" $200 by not providing sufficient memory on a laptop, such that every hour of coding is sluggish due to a slow machine.

For many groups, a manager refusing to fund this kind of software engineering "equipment" (sounds classier than just "tools"), is like telling a construction worker to dig a trench - but we can't afford a $20 shovel, so use this spoon instead. Again, if a company is creating a 5 person development team, better to have only four people, but funded with the right equipment, then five developers who need to dig with spoons.

Problem 3: "We cannot afford that book - just see if you can figure it out from free, online tutorials."

Of course everyone knows that continuing education is vital in software engineering. In the manager's perfect world, they have a team of self-motivated developers who study on their own time, paying for their own materials, and learning at their own expense. And then, the manager (who has contributed nothing) gets to benefit from having all these learned developers. While yes, a developer is ultimately responsible for their own learning and career, a wise manager would realize that the company has a huge vested interest in the developer's learning, and would hence do things to encourage that learning.

Perhaps the most basic thing a manager could do is to have the company pay for a book that the developer is motivated to read. A book costs between $30 and $50 dollars. If a developer spends 20 of their own hours (on nights and weekends) over a month reading and absorbing that book, such that they can now profit the company with a new skill, this is a no-brainer. It could cost management thousands to send a developer to training (plus the days off work). It could cost management additional thousands to fix mistakes resulting from the developer not knowing that profitable technology. A book is cheaper, can be re-read by other developers, and is often read off the clock. Money speaks, so if management can't even encourage a motivated developer's learning with a $30 every other month, they're effectively telling developers that management doesn't value learning.

Tuesday, April 28, 2009

Bad estimate trick - playing people off of each other

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/bad_estimate_trick__playing_people_off_of_each_other.htm]

One estimating technique I occasionally saw in consulting, which I thought was pathetic, is as follows:

The consultant faces a domain-specific problem that they're not familiar with (say writing reports, or doing some database optimization, or wiring up a backend service). So, they intend to sub-contract it out. They interview two separate contractors, and ask each for an estimate. The consultant, in their sneaky mind, figures that they'll play the two contractors off of each other to get the "real estimate", and whichever estimate is lower must be the honest and correct one.

The biggest mistake I see here is the bias that whatever is lower is more correct. Developers are notorious for low-balling estimates (especially if the manager demands a low estimate in order for the developer to continue), so this is historically a bad bias. It's just as likely, or more likely, that the higher estimate is actually closer to the truth.

I think a much better approach is to find a way to determine who the more reliable and experienced developer is, and go with their estimate, even if it's the higher one.

Monday, April 27, 2009

BOOK: Patterns of Enterprise Application Architecture

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/book_patterns_of_enterprise_application_architecture.htm]

I remember when Martin Fowler's Patterns of Enterprise Application Architecture came out back in 2002. I constantly heard good things, but never got around to reading it. Finally, I buckled down and went through it, and I'm glad I did.

Perhaps the biggest thing I liked about the book was the common vocabulary. Whenever I look at popular community projects (such as Enterprise Library, CLSA, or .NetTiers), or just read star bloggers, ones keeps hearing about all these pattern names (ActiveRecord, Gateway. Lazy Load, Repository, Registry, Service Layer, etc...). While gradually you pick them up, it's convenient just injecting them into your brain all at once.

I also thought his chapters on concurrency were excellent, especially how he explains the difference between an optimistic lock and pessimistic lock. (My simplified interpretation is that an optimistic lock is "optimistic" in that it assumes conflicts are either rare, or easy to resolve, and hence checks for conflicts at the end of a transaction. On the other hand, a pessimistic lock is "pessimistic" in that it assumes conflicts are either common, or very expensive to resolve, and hence prevents the conflict from ever occurring by locking at the beginning of a transaction).

He's also very "no-holds-barred" for doing things the best way. For example in the Metedata Mapping pattern he emphasizes using code generation or reflection - two concepts that for some reason many developers seem reluctant to use.

Lastly, reading a solid book like this just helps you think more about enterprise patterns as you go through your daily coding, and that's a valuable thing.

 

Sunday, April 26, 2009

Structs vs. Classes - seeing the functional difference

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/structs_vs_classes__seeing_the_functional_difference.htm]

There's a lot written about the difference between classes and structs, and comparing the two.

One thing I find helpful to really "get it" is to whip up a quick unit test, and functionally see the differences. While classes (being reference types) and structs (being value types) will have different memory and performance implications, it seems most devs are initially concerned with how they're functionally different, and they worry about performance "later".

Here's an example showing both a struct and a class object being passed into some method and having their property updated. The struct, being a value type, is copied when sent into the method, and hence the property doesn't "persist" outside of the method (the copy is discarded, the original left untouched). However, the class sends in a reference, and therefore the method is pointing to the same instance as the host caller, and hence the update "persists" for the class..

    [TestMethod]
    public void TestMethod1()
    {
      MyStruct s = new MyStruct();
      s.Name = "Struct1";
    
      MyClass c = new MyClass();
      c.Name = "Class1";

      UpdateStruct(s);
      UpdateClass(c);

      Assert.AreEqual("Struct1", s.Name);
      Assert.AreEqual("newClass", c.Name);
    }

    private void UpdateStruct(MyStruct s)
    {
      s.Name = "newStruct";
    }
    private void UpdateClass(MyClass c)
    {
      c.Name = "newClass";
    }

    public struct MyStruct
    {
      public string Name { get; set; }
    }
    public class MyClass
    {
      public string Name { get; set; }
    }

You could write tests for similar things - like showing how structs don't allow inheritance (which actually wouldn't even compile), but do allow interfaces. You can drill down even further by stepping through in the debugger, or checking Visual Studio's performance wizard.

Tuesday, April 14, 2009

Tips to incrementally check in code without breaking the build

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/tips_to_incrementally_check_in_code_without_breaking_the_bui.htm]

No one wants to break the build. However, every time you check in code, you risk breaking the build. This leads some developers to avoid checking in for days (or weeks!) until they have a dangerously-big component. That has its own problems. Integration is pay-me-now-or-pay-me-later. I'm a big fan of paying upfront with small, continuous check-ins. Here are some tips to do check-ins without breaking the build:

  • Try to do multiple smaller commits as opposed to one giant commit.
  • Where reasonable, try to keep a component split into multiple smaller files instead of one giant file, especially if these files are updated by many developers. This reduces contention, and hence likeliness of breaking the build.
  • Check in a file that won't hurt anything, like a class file that's not added to the project yet.
  • Make sure you understand how code-generation integrates into your build. It's easy to have the code "work on your machine", only to have a code-generated script on the build server overwrite your changes and break the build. Make sure all your local code is in sync with what will be actively code-generated.
  • Make sure you always check in all the needed files, especially files that get "registered" with a master file list. For example, C# files get registered with a csproj project file.
  • Use a source control that allows merging (SVN, not VSS)
  • Split your code into isolated components - i.e. reduce dependencies in your code.
  • If you're working on a unit test, and you "need" (?!) to check in a partially-completed test that currently breaks, then consider applying the "Ignore" attribute so the test doesn't run yet.
  • If you really need to check it in, perhaps comment out the breaking section.
  • If you're checking in to send code to another dev, consider not checking in, and sending them a patch instead
  • If you're checking in to the global trunk just to "back up" your work, consider checking into your own private branch.

Monday, April 13, 2009

The non-financial resources at a manager's disposal

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/the_nonfinancial_resources_at_a_managers_disposal.htm]

A good manager knows what resources they have at their disposal, and how they can exchange those resources for other things. The most basic resources are budget and headcount. But a creative manager can find a lot more:

  • Offering interesting projects and opportunities
  • Letting developers work from home (less driving is good for the environment too!)
  • Offering your time to hear out the devs.
  • Opportunity - If a dev is interested in a certain new technology, consider offering that if they research this task on their own, then potentially the team can leverage it - which means they can learn a ton more about it.
  • Work hours - to avoid rush-hour, or coordinate with work-life balance, let the devs come in an irregular hours (like 6am-3pm).
  • Offer encouragement - some developers are motivated knowing that their boss supports them and publicly appreciates the good job they've done.
  • Permit devs to install safe games on their laptop.
  • Give them a "free" PTO day to go to an in-town conference (Yes, time is money, but for some reason, mgrs and bureaucracies are more apt to give you time than money).

Even a little money can be stretched a long ways:

  • If they're working overtime at the office, consider at least buying them lunch or dinner. I remember on a death-march consulting gig when my manager kept bringing us lunch. He explained that if we're working 4 hours of overtime (say $400 billable dollars), he could at least help by getting us a $10 lunch. I thought he was a really good manager. Sure, he got the better end of the deal, but it was still a nice gesture.
  • Buy a book to encourage them to learn. Yes, it's ultimately the developer's responsibility to learn, but if they're going to spend 20 hours pouring over a book to learn a technology that helps the company, a $30 investment is a no-brainer.

Thursday, April 9, 2009

We need to get this done

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/we_need_to_get_this_done.htm]

Anyone can say “we gotta get this done ”. Sometimes this is just a broken record - everything is top priority and needs to be done now - but sometimes a specific task is truly on the critical path and is blocking other people.

Telling a developer to essentially "hurry up" won't get things done faster, it will just annoy the developer, or perhaps make them hurry and write sloppy code which will cost you more in the long run.

While I'm certainly no management expert, I'd expect at least a few questions you could ask any developer are:

  1. Everything considered (other tasks, meetings, misc distractions, research time, expected delays, possible overtime) - what date and time can the developer have this done by? Note that you want a date, not "how many hours do you think this will take". An 8-hour task may spread across 3 days if there are other distractions. Get an honest, unrushed date based on the developer's estimate. Note that you also want a time. Does "Wednesday" mean 8:00am, or midnight? This also gives the developer a concrete goal to shoot for, as opposed to "get it done real fast".
  2. Is there anything that can help the developer get this done faster (delegate sub-tasks, better hardware/software, tools, a technical roadblock holding you up, pair programming with another dev)? The goal is for the manager to offer practical help by shifting around resources. If this task is really so important, then it is important enough to provide extra resources too.
  3. Acknowledging that surprises do come up, so you understand if the date cannot be met, but the developer should at least alert you as soon as they reasonably think they can no longer meet the date - and provide an updated estimate. The goal is to not get suddenly surprised on the target date with a late feature.

Of course, it also helps to work in smaller increments with verifiable milestones along the way. It can be easier to manager 5 small 1-week "milestones" than a single big 1-month project.

All of these involve give and take. Yes you can have it be a certain date, but the developer determines what that date is. Yes you can have it earlier, but you need to provide the developer more resources. Yes you won't be surprised on the target date with bad news, but that's because the developer is encouraged to tell you the bad news up front.