Characteristics of a Software Professional

At work, I have been challenged with the question “What are the most important characteristics of a software developer?“. This is a tough question, and no matter what you decide to include, you have to leave something out.

I’ve been part of software development projects in various companies. The successful projects teach you invaluable lessons. The dysfunctional projects even more so. Inevitably, a list of characteristics would include qualities I value and desire in my fellow colleagues, as well as characteristics I’d expect them to want in me. (So this is also a long todo list for me. ;)

To get some kind of structure, I decided on three main categories: Professionalism, Long-term code and Quality mindset.

Professionalism

Take responsibility

You are a professional developer, and professionals act responsibly. If things go wrong,
take responsibility. Understand why things went bad. Learn, adapt and make sure it
never happens again. When faced with a difficult choice, “do the right thing”. Optimize for the long run even if it results in more work today. Be a team player, even if this means saying no. Speak the truth.

Know your product

We’re part of a business. Without successful products, there will be no business.
Know your users and their needs. Use your product, use competitor’s products,
visit customers and watch them use your product (from purchase/download to
installation to day-to-day usage to upgrade to uninstall and so forth).

Continuous learning

Be humble and practice relentless inquiry. Question everything (since everything has potential for improvement), embrace questions on your code, realize others’ suggestions might improve your work, be happy other developers change “your” code
(it’s good enough to understand!). Improve yourself and others. Become a better developer by reading books, papers, blogs etc. Watch instruction videos, listen to podcasts, try new technologies, participate in open source development, discussion groups etc. Discuss your code and what you read with your peers. Talk to developers of other specialities. Teach others what you know well.

Long-term code

Communication

You write a line of code once, but it is read hundreds of times. Invest time to write code easy to read for others. Write code at the right level of abstraction, abstract enough for expressiveness but without hiding necessary detail. Adhere to design principles as
they capture proven ways to high-quality code. Apply design patterns to better communicate your intent.

Maintainability

Decouple the different parts of your software, on every level – sub-system, module, class and function. Write extendable code, so that you can add functionality with minimal change to existing code. Avoid technical debt, and repay debt as soon as possible. Interest has to be payed on all debt.

Proven functionality

Never deliver code unless you’ve proven it works. If you don’t test it, it will be faulty.
Write testable code. Make it testable from the start, later it will be too expensive. Automate your tests to run before check-in, after check-in and nightly. If the tests are not executed automatically, they will not be updated and soon be obsolete. Without automated tests, no-one will dare change any code. Write fast and reliable unit tests. Write realistic integration tests. For each new feature, write acceptance tests. Automate everything.

Quality mindset

Quality is your responsibility

You, as a developer, is responsible for the quality of the product. Other roles can help you spot problems or give you more time, but they cannot affect quality. Never ship anything without being certain of its correctness.

Find bugs early

Find bugs early in the development process. If a bug can be found by the developer, it should be. If you need tools, get them. If you need hardware, get it. If a bug is found late, understand why it was not found earlier. Fix the process so that bugs of this kind never slips through. Automate.

Fix it now

If you find a bug, fix it now instead of filing a bug report. Ask your colleagues to help out. You will save time. File bug reports on things that couldn’t be solved in half a day.
Do things properly the first time. If you don’t have time to do it right today, when are you ever going to find time? Give time estimates that allow you to produce quality products. Think about what is stopping you from being more productive. Fix it, and then move on to the next thing stopping you.

If you’re interested in these things, you should have a look at Poppendiecks’ “Lean software development” books, Senge’s “The fifth discipline“, Martin’s “Clean coder“, McConnell’s “Code complete“, McConnell’s video “World class software companies” and others. I also provide some resources in previous blog posts (e.g. videos and books).

What characteristics do you value in a software developer?

Great Videos (and Articles) for a Software Developer

Commuting to work by public transportation? Doing the dishes? Regardless, you might want a distraction. I found some time during the holidays to look at some new articles and videos on the web. (This is a digest from my Twitter feed. Follow me @johnnybigert.)

Great stuff:

  • Steve McConnell – brilliant as always. What makes a World Class Software Company? video
  • Great talk on API design by Joshua Bloch. video
  • “JavaScript the Good Parts” video. Here’s something you (or I) never expected me to say: JavaScript is a really cool language! See for yourself: video
  • No refactoring? Good article on design principles: “SOLID is append only”. article
  • Nice paper on how Spotify’s peer-to-peer technology works (by former colleagues from KTH :) article

Good stuff:

  • Demo of how to set up an Windows Azure project and run it locally. Extensive prerequisites! video
  • Local file storage, 3d animation, audio analysis etc. in HTML5 today! Demo/presentation video. video
  • Intro video, Amazon Web Services: wow! CloudFront, Queues, SimpleDB, MechTurk, Private Cloud, DNS… It goes on and on! video
  • Confusing presentation but great message: “Jellyfish makes sure your common JavaScript code works for any browser/target”. video
  • Nice intro to jQuery from a twelwe-year old kid(!). I’m humbled. video
  • Domain driven development? The “Supermodel” DDD framework: “make simple MVC stuff easy and complex stuff possible”. video

Behavior Driven Development

Behavior Driven Development (BDD) is a flavor of Test Driven Development (TDD). In BDD, we have a specification focus instead of a test focus. What does that mean? And how can it help us write better software?

I just watched Dave Astels’ talk on “Beyond Test Driven Development: Behaviour Driven Development” (video). The first time I ran across Behavior Driven Development (BDD), it struck a chord. It is branch of Test Driven Development (TDD) that suites my style. And as always, hearing someone else’s viewpoint makes you think about your own practices. I definitively learned a lot from the video which describes the rSpec BDD framework (for Ruby). Let’s review some highlights of BDD.

As mentioned, BDD is related to TDD. In the video, Astels stresses the fact that we should try to get away from the testing mindset, and focus on writing specifications of the system behavior instead. In BDD, we have a specification focus instead of a test focus. The name of a BDD test case should read as if it specifies a small piece of system behavior. For example, let’s say you’re writing software for a web shop (as in the wikipedia article on BDD). One test case could be named “refunded items should be returned to stock” (or refundedItemsShouldBeReturnedToStock). The test code is there to clarify the details of the specification.

From a philosophical standpoint, the word “test” makes me think of testing something existing, while “specification” makes me think of specifying the behavior of something not yet built. It might help your thought process when decoupling the test cases (= the specification) from the underlying implementation. This ties into one of the drawbacks we often see with traditional unit testing. A recurring pattern is e.g. a ShippingOrder class with a corresponding ShippingOrderTests test class. This tightly couples the test code with the production code. Refactoring becomes painful as test classes might become obsolete if you decide to split a production code class in two.

Instead, Dave Astels mentions that in BDD, you should organize your test classes not around production code classes, but test fixtures. Each test class has a test fixture, and that fixture captures a specific system setup. (In short, a fixture creates objects from your production code classes in a setUp() function and cleans everything up in a tearDown() function. The setUp() function is executed before each test case in the test class and tearDown() is executed after each test case.) Thus, all tests in a test class would run against the same system setup. For example, if several test cases revolve around returning or refunding items in your shop, create a RefundItemTests test suite.

Since system behavior is not restricted to a single method or class, the notion of “unit” in “unit testing” needs to be widened. Any reasonable subset of the code could participate in the test fixture (even the full system, as described in my post on edge-to-edge unit testing). I like that, since it allows you to find and test on the stable boundaries within your system, thus making the tests less brittle. This should be contrasted with having a one-to-one correspondence between production and test classes, which will be very brittle as the code evolves.

If you have good or bad experiences with BDD, or just random thoughts on unit testing, please drop a line below.