Wednesday, April 29, 2009

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.

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

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

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.

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..

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.

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.

Monday, April 13, 2009

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.

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

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:

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".

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.

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.

Wednesday, April 8, 2009

Say you want to do continuous development, with quick demos to management (or business sponsors) every week. One thing I've found useful is to nix the projector. I've been in places where in meetings, you can't show something on a computer unless it's on a projector. And of course for large meetings and official presentations I can see the benefit. However, if you want just a small and quick sanity-check meeting, there are several benefits to nix the projector:

Faster setup - I've seen endless problems trying to hook developer machines up to a seemingly innocent projector (can't turn on the projector, need to install special sofware, your laptop won't register, the screen doesn't show, different resolution sizes, adjust the font size, bad glare from the windows, etc...). If you only want a 10-minute "spot-check" demo, you don't want to waste even 5 minutes setting up a projector.

Smaller crowd - Something about human nature seems to be drawn to a presentation on the big screen (Maybe people think the bigger the screen, the more important, and they don't want to miss out on important things). However, by having just a laptop screen, it forces you to have a smaller crowd - maybe 5 or 6 people at the most.

Easier for multiple machines - Switching a projector between multiple laptops can also be risky (see "faster setup"). If for some reason you have multiple laptops (say you haven't integrated all the pieces for the demo onto a single machine yet, or you're showing very different scenarios that don't "fit" on one laptop), not having to worry about switching the projector can just make it more convenient.

Easier room requirements - A lot of offices only have a few "special" rooms that contain projectors - and these rooms are usually already booked. Not needing a projector means you aren't limited to these special rooms, and therefore have far more room options available.

I realize it's trivial in the scheme of things, but not needing to worry about the projector can eliminate some of the red tape and setup that distracts you from the things that aren't trivial.

Thursday, April 2, 2009

I continually try to get more involved in the developer community (such as via user groups and tech events). This gives me the opportunity to talk to developers across a wide spectrum of different projects. One type of developer, for whom my heart really goes out to, is the lone developer struggling in isolation. They're trying, but they're on a team of one - the only consultant on a project, a remote developer working from home, or the only developer in a one-person "department" of a small company.

The problem is that software engineering is too hard to do alone. It's easy to feel like you're on the outside looking in - while other departments have niche experts and devs to cover your back, you're left all by your lonesome to figure out the entire thing yourself.

Sometimes you can get out of the situation - switch jobs or press the business sponsors to hire a secondary dev (do they really want the entire project resting with one person, without any backup if you become unavailable?)

However, even if you cannot change your department or project's headcount, you are still never alone. Especially with the online developer community, blogs, forums, user groups, conferences, books, and the like. It is one joy of software engineering in today's world - you are never alone.

Wednesday, April 1, 2009

New technology is constantly coming out. Some of these are small - a new tool, a special trick, or some open source library - and these can be learned easily enough. However, every few years, there's a fundamentally new wave of technologies that makes the previous wave obsolete. For example, classic ASP to ASP.Net 1.0, to ASP.Net (3.5 with Ajax, JQuery, and MVC) to Silverlight. - every few years there's a significantly more powerful UI technology.

So, the question becomes, how do you continually keep up with the next wave?

You have three main categories of options:

Your company trains you. This was popular during good economic times. Some companies have a training budget based on a percent of the employee's salary.

The last option speaks for itself - but there's a difficult balance between the first two. Every developer should be able to ask their manager "What role, if any, does the company have in assisting me to learn the next wave of technologies?" Every manager should have a ready answer.

Realistically, you need both internal motivation and external support. For example, if your company won't even pay for a $30 book on a hot new technology, then you're screwed. On the other hand, you simply can't learn a whole new technology by passively skimming blogs during your lunch hour.

Personally, I'd emphasize the concept of an upward spiral. If you want to be a decent developer, be prepared to invest:

Time - prepare to spend on average of at least 8-10 hours a week doing continual education. Maybe you're working 60+ hour weeks at your company, and the 10 hours is part of that. Maybe you have a "cushy" 40-hour week job and you do the 10 hours on your "free time". Sure, there are weeks (or even entire months) where life needs you to take a break. Likewise, there will be other times when an in-demand tech first comes out that you may be sprinting.

People - Try to get to a live-person event at least once a year, such as a user group or conference. Also, explicitly seek out peers who you can collaborate with (even doing informal code reviews with your coworkers, or discussing ideas during a lunch break).

Blogs - Use a blog aggregator to continually monitor the industry leader's blogs. This will give you a heads up of new techs coming down the pipeline, so you can prepare. If the tech actually has potential (as opposed to just some other buzzword), you'll see it light up on multiple people's blogs.

Books - Especially for a new wave, or for matured design patterns on existing techs, try to read a full book at least twice a year (I think once every other month is more ideal, but there's a balance).

Projects - If you have the opportunity, put in the extra work to get on a project that uses a new technology that appeals to you. Ultimately, the best way to learn a new tech is to actually use it, and unless you use it on a real project, you'll always remain a hobbyist.

Essentially, learning a new technology takes hard, pro-active, work, which many devs are already willing to do. The question becomes how to best maximize your investment on that hard work.