Selfish Development

July 10th, 2008 - No Responses

I think one of the main reasons we, as developers, start programming is to express ourselves creatively. It’s the creative process that keeps us coming back for more: There is nothing more rewarding than distilling down a seemingly complex problem to a simple solution. This doesn’t need to happen in the code first. The reward usually happens much earlier during the discussion about the problem with your team members (fellow developers, analysts, customers etc).

Of course this is true in any field. Oliver Wendell Holmes Jr. (1841 -1935) Once said “I wouldn’t give a fig for the simplicity on this side of complexity; I would give my right arm for the simplicity on the far side of complexity”. If he was talking about software development, I believe he would be saying that it’s not enough to solve the problem. We need to solve problems in ways that other people can understand and use.

As a developer this means writing code that’s explicit about your intent. In Bob Martin’s words, “The name of a variable, function or class should answer all the big questions. It should tell you why it exists, what it does and how it’s used”. Eric Meyer sees it as trying to tell as much truth about your intent as possible. You can’t tell the whole truth, due to the nature of abstraction, but you must try. Doing so will help you avoid the over abstraction syndrome that plagues source code (Over abstraction occurs when important information is abstracted away too early, requiring the reader to divert down a side path to understand the solution). I’ll talk more on this in a coming post as it requires a discussion of encapsulation and cohesion.

So what does this have to do with selfish development? Put simply it is this - If you are worth your money as a developer, your code will be read many times and there’s a cost to reading and understanding code. So good code is easy to read and understand. If its easy to read and understand then its more than likely easy to extend. It also needs to be correct in a manner that can be proven when required. This provides confidence to you and those who will use or maintain the code in future. So it needs automated tests and excellent (not good) coverage. With this in mind, team members should avoid writing dirty, untested code under the premise of - “I just need to get something out. We can come back and clean it up later”; or my favorite, “I’ll get it working and you can make it pretty”. What’s actually being said is, “I’m too lazy to do a proper job but I want to enjoy being creative. You can deal with my stuff once it works (do maintenance). Oh and don’t ask me to explain how it works. I’m not good at explaining things”.

It’s of no difference if you’re a team of one or many; Pairing or flying solo; It’s not done until it works, is testable and understandable.

One of the “tells” of this process is someone who wants to provide a solution in a technology before they understand or have defined the problem (bottom-up programmers): The implementation nuts, who are crazy about the latest api or library out there. It’s like a person who needs to hang a picture on the wall. Straight away s/he runs out, grabs a nail and a hammer and starts banging.  Unfortunately, the picture must be hung in a specific area and a reinforced steel girder occupies that area. Our friend keeps banging away, saying “hang on, I’ve almost got it” … you can see where this is going.

The alternative is to talk about the problem; Code by intention; top-down; Write the class or function that answers “Wouldn’t it be cool if I had an object that did…” and worry about the implementation afterward. While your at it, you might as well test using Test Driven Development (TDD). Doing so requires you to understand the problem you need to solve before you try to solve it with the detail (take a squiz at testing with mocks, interfaces and abstracts). It also allows you to concentrate on defining the problem in an abstract easy to understand way before getting into the noisy detail of exactly what you will use to provide the solution.

My personal experience is that a well defined, high level solution to a problem, written in the conceptual layer, leads to less coupling in your system allowing you to dangle implementation details off you abstractions, one at a time. For complex systems, it’s much easier to understand a small bit of implementation detail, trusting that the system is correctly communicating among its components to solve the greater problem, than to think of everything at once (the details and how its going to communicate with other parts of the system).

I’ve worked with people who have criticized other developers because they talk about the problem too much before putting something down. Personally, I like these guys, they use the best computer, our brains, which are largely configured to quickly compile and optimise language, before proceeding to the more expensive writing of code. Refactoring helps but is no match for an open discussion about the problem and how to simplify it among people.

One further comment: I was careful in my post to use developer and programmer in specific places. I believe a programmer is someone who knows how to solve a problem with a given language or api without regard for the true elegance required in a well designed system that is very easy to understand and change. A developer is something again. S/he is someone who is considerate to the users of the code base, customers and other developers. In doing so, they seek clarity of intent and elegance in design of a maintainable system. They have values (I’ll rant about this in a future post), principles and tested practices. They can justify their values and principles and constantly test their practices. aahhh, this is getting a little to zen.

Stepping down from my high horse: Before I was a developer, I was a programmer. I’ve been guilty of everything I’ve spoken of in the negative. I try to improve the readabilty of my code, with every line I write, leaving in a better state than I found it. My success varies, but over time I’m improving … I have a long way to go. I would appreciate your comment.

Naming Interfaces and Concretes

March 6th, 2008 - One Response
Recently, I had a short, interesting discussion with a few Smartpath developers about conventions for naming interfaces.
Two conventions were evident in their source code. I’ve used both in the past :-)
  • Prefix interfaces with ‘I’
  • Name interface by role and suffix its concrete implementation with “Impl”.
Neither sit well with me. I prefer to name Interfaces by their role and concrete classes by their specific implementation of that role. This allows me to write code with clear intent and consider that the readers of my higher layers may not always be developers. I’d like to think business analysts could read the higher layers and understand the intent.
Consider the following points:
  • Code to an interface - that is, create and assign concrete types to their interface or public type (contributes to the flexibility and longevity of code base)
  • Always try to write readable code (I once heard and like the idea that you should always code as if you’re writing a letter to another developer or business analyst).
  • Hide the details or plumbing in lower layers.
With these points in mind, its nice to lay down code in a format very close to english sentences. This is particularly important in the higher layered code, like the application layer.

User Story: As an operator, I search for a clients contractual information using <some identifier> …

Implementation:
ContractRepository contractRepository = getContractRepository() ;
contractManager.loadsContractFrom(contractRepository, id);
or, if you’re more inclined toward using builders:
contractManager.uses(client).toLoadContractFrom(contractRepository);
Looking at the contract repository, we’re not interested in the concrete implementation. My currency in this transaction is the interface, which clearly indicates that I’m using a type of contract repository to load the information, without clouding the issue with lower level details like the specific type - local database, cached area or gateway to another system.
public ContractRepository getContractRepository()
{
return new TemplateGateWay(gatewayCredentials, gatewayAddress);
}
So it makes sense, from the readers perspective, to say ContractRepository, not IContractRepository.
Likewise, it makes sense to provide a specific name to the concrete type like HibernateContractRepository or ContractGateway, not HibernateContractRepositoryImpl or the like.
There are times when choice of name is not as clear. For instance, we often face a situation where we have extracted an interface from a concrete to satisfy TDD (suspecting that the area may be a spot for variation in the near future). This is usually a case where our concrete is the default implementation of the interface or type.
In these situations, I like to use Default<Type name>. i.e. DefaultContractRepository() (this is a poor choice as I would never associate default with this type of role). As new concrete implementations are added, I either rename the Default type to a specific name or use it as an instantiatible base of the other concrete types.
I’d like to add another parting view:
Code is read more than its written. As such, its important to make your code readable to the widest audience possible. This increases its life span, reduces its cost and instills trust in your fellow developers and wider business collegues.
I’m interested in anyones comments about this topic.

Conceptual Integrity

August 12th, 2007 - No Responses

Conceptual integrity of your software solution is arguably one of the more important factors to focus on, increasing understandability, maintainability etc.

One way to maintain conceptual integrity is to apply the Domain Pattern. Two good resources covering Domain Driven Design (DDD) are:
•    Domain Driven Design, Eric Evans 2004
•    Applying Domain-Driven Design and Patterns, Jimmy Nilsson 2006

An application’s conceptual language takes centre stage in DDD, allowing business owners and developers to talk the same language. A clear, simple conceptual language shortens the divide between business analysts and developers, during their feature discovery cycles.

I can’t stress enough: Good software is all about good communication. Agreement between project stakeholders, to work toward a simple conceptual language modelling real-world processes will improve the project’s chances of success.

Maximise understandability by minimising overloaded meaning.
If there is more than one word or phrase to describe a process, try one of the following:

  • Look for a more specific word, that narrows meaning. “Entity” is a pet hate of mine. Seriously, unless accompanied by a domain specific context, get rid of it. Substitute it for “Thingy” - at least it will scream attention as you increase domain fidelity.
  • Agree to use one word and actively ensure all conversation participants support the decision. This decision should come from the business owners.
  • When neither word suitably describes the overloaded meaning, the issue is usually one of context. Extract the contextual meanings and distill into one description for each context. Agree on a single abstract word for the original overloaded word. The abstracted word and one of the context descriptors will then be used to narrow meaning in the domain.

Step 12 in “The Joel Test”, which documents 12 steps to better code, asks if you do hallway usability testing. I feel this testing is really challenging your Domain Model using your conceptual language.

Continually test your domain model’s power, flexibility, complexity and conceptual integrity:

  • Can it answer a question required for your next iteration?
  • Is the answer way to complex or a little vague?
  • Are there several ways to answer the question, and if so, is it an early indicator of a domain model or conceptual language smell?

This is my way of hallway testing…as a spontaneous design session. Don’t be afraid to put your domain model, or parts of it, on the wall for all to see. Put post-it notes on the model with questions you expect the model to answer (i.e. Can user x searh all assets owned by business unit y?). Encourage others to comment, question and amend through this shared process.

Remember, the more “cold” eyes on a problem area, the better chances that problem has of being resolved properly.

Work Life Balance and Worry

December 28th, 2006 - No Responses

Today I had lunch with a friend, who mentioned this blog. I thought it was time to make another entry and dump something I’m grappling with at the moment….

Since accepting a management position, I’ve found myself in constant battle maintaining a work to life balance.

Some things I worried about:

  • How to keep my team happy and provide adequate service.
  • How to keep my clients happy and in doing so maintain or improve my company’s reputation.
  • How to make time for my partner
  • How to set myself up for family and by that I mean - not progressing down a path where work consumes late nights and weekends. I want my kids to know me and I want to love and experience as much of their growth as possible.

You get the idea … I’ve tied worry to life balance bacause I find that even when not at work, its easy to take home the worries of the day.

So here are some early tools I’ve found to maintain balance and combat worry:

1. The first is a quote by Brian Dyson (CEO: Coca-Cola) on life balance. I use it when making those work or family decisions (when it always seems to be work):

“Imagine life as a game in which you are juggling some five balls in the air – work, family, health, friends and spirit – and you’re keeping all of these in the air. You will soon understand that work is the rubber ball. If you drop it, it will bounce back. But the other four balls – family, health, friends and spirit – are made of glass. If you drop one of these, they will be irrevocably scuffed, marked, nicked, damaged or even shattered. They will never be the same. You must understand that and strive for balance in your life”

2. Having a plan of action returns the power to you. Answer the following questions empowers you.

  • Whats the worst that could happen?
  • Accept the worst as an outcome?
  • Devise a plan to improve on the accepted outcome?

3. Process for dealing with problems and worry at work from Dale Carnegie’s “How to stop worrying and start living”:

  1. Write down a clear problem statement - What am i worrying about?
    • Take time to collect facts about the problem
  2. List all solutions and their probable consequences - What can i do about it?
    • Strive to keep emotion out of thinking for solving problems
    • Pretend you’re impartial, collecting information for someone else.
    • List all possible outcomes against and for each solution
  3. Choose the best problem solution
  4. Action the problem solution - do something about it.
    • At this point, stop thinking about worrying about the consequences. The time for thinking has past and its time to commit to action.

What about the module?

October 3rd, 2006 - No Responses
We rightfully create objects that are loosley coupled and cohesive - you bet. But, we fail to look beyond the object level to that of the module. All things being good, these modules should exhibit the same traits - being highly cohesive and loosley coupled. So what are we really saying here? Well, we’re looking for controlled ways for modules to communicate with one another while limiting dependencies on one another. We’re looking to provide a single interface, representative of the module concept; To facade multiple sub-module interfaces which cohesively describe how the module performs its function.
Further, we’re looking to extract entities that have identity across all modules. These we abstract to a meta layer (call it what you will) and provide to modules via injection. Thus reducing module dependency on one another.
A poor example: A system that stores information about members, their subscriptions and the events they wish to attend. Modules might be:
  • Membership - capture, modify and return membership details
  • Subscriptions - Fees and subscriptions associated to members
  • Events - Organising and booking of industry events, members my wish to attend.
Module interfaces should reflect corse grained functionality - “what to do” rather than ”how to do it”. Our meta layer would definitely have a Member entity since its common to all modules - holding identity across the entire system.
I could go on but I’m hoping this is enough to get the coggs whirring in there. Its really no different to the decisions we make at the object level. However, it does change the forces acting on design decisions at the object level … thoughts?