Thursday, May 15, 2008

Defensive Programming

Enough negativity after the last post, let me get on to a more interesting topic. When I was in college, I learned how important it was to code defensively. I'm sure many folk who studied computer science was also exposed to this way of thinking. In case you don't know what I mean, I am referring to the practice of checking values, typically parameters that are passed into methods, so that the method does not blow up if it encounters a null, for example. 

void renderShapes(Shape s) {
if (null != shape)
s.draw();
}

So this is a very trivial example, but when this effect is compounded, adding all the checks for validity, generates a considerable percentage of extra code, non of which is actually necessary, in fact, just the opposite, it adds complexity and makes programs harder to read and maintain. Its all about trust, the correct place to check for validity is at the entrypoint to your system, whether it be via computer-computer or human-computer interface. Doing this, results in data validity being checked only once, but its then valid all the time.

Consider an object's contract. If the contract contains a method that states give me a valid X, and I will produce you a valid Y, then anything less than a valid X and the caller is to blame.

I found this great description from years back -

3.13 Do not program "defensively"

A defensive program is one where the programmer does not "trust" the input data to the part of the system they are programming. In general one should not test input data to functions for correctness. Most of the code in the system should be written with the assumption that the input data to the function in question is correct. Only a small part of the code should actually perform any checking of the data. This is usually done when data "enters" the system for the first time, once data has been checked as it enters the system it should thereafter be assumed correct.

Example:

%% Args: Option is all|normal
get_server_usage_info(Option, AsciiPid) ->
Pid = list_to_pid(AsciiPid),
case Option of
all -> get_all_info(Pid);
normal -> get_normal_info(Pid)
end.


The function will crash if Option neither normal nor all, and it should do that. The caller is responsible for supplying correct input.

Wednesday, May 14, 2008

Tired of doing the right thing

Some days, I just get weary of trying to keep things simple and honest. Don't know how others feel about this, but two or three mad phone calls or meetings with folk who simply want to add to the problem, rather than focusing on a solution makes my blood boil.

This is nothing specifically to do with software development, there are people like this in all walks of life. I would wager a pint or two however that great organizations stamp on this kind of thing, and that's exactly what makes them great! Sure, its human nature, protectionism etc, but its still painful to deal with

When a day contains one too many conversations where
- waste over sufficiency
- confusion over clarity and comprehension
- speculation over conversation/resolution
- complexity over simplicity
- procrastination over immediate action

have been prominent, I lapse into a state of indifference.

As someone once said to me, just relax and take the money.

Pass me my drink :)
Ahhhh. I'm calm.

Wednesday, May 7, 2008

Agile Management

Is there such a thing? Is this a misnomer? Is there a need for managers in agile teams? I don’t think there is a simple answer to this one, and coming from an agile development background, I have since converted to be a development manager. What does that mean exactly? There is no hard and fast definition of what a dev manager is, but I think there is a need for someone who comes from a development background and understands the real issues that development teams face – many PMs that I have worked with simply don’t understand the problems. Obviously, these job titles are simply labels, but they do carry baggage and assumptions with them.

So, what do I do as a development manager? Well, firstly, I try to act as a communication bridge as much as is possible, and like it or not, there is definitely a gap here within most teams. Often development, business teams, and leaders don’t communicate enough – probably for seemingly valid reasons, but this communication is crucial to the success of a company. Business leaders don’t understand (and niether would I expect them to) how complex software development is, so it’s the responsibility of people like me to work with them and help them understand all about value and prioritization. Of great importance to me is also vision and custmer assignment on a project, without these key pieces in place, developers feel like they are in the dark, they want to know they are building a ’cathedral’.

Most of all, the development team manager must remain humble and remember that they are there to facilitate great team working – you are only as good as your team. My goal is to have my team reach its full potential, and currently, I consider myself priviledged to be working with a very talented team. Its early days for me, and I am far from where I want myself and my team to be, but I am excited about the future and know that I can create a fun and safe atmosphere within which team members can excel.

Of course, there is an irony here, the longer I am away from the harsh realities of the coal face of software development, the more I forget about how tough it is to deliver something. So, its my goal to work on home projects, where possible with friends to keep me ‘honest’ but I see it as an almost impossible conundrum. Its almost as if I would like to work for a little time as a manager and then get back to development for a time and so on.

I do believe however, that there is a valid role for a manager. If nothing else, to remove the pressure on the team from outside influences to allow them to do the right thing without fear – thus getting the best and most creative talent to reveal itself in the team members.

Monday, May 5, 2008

Aloof Agilty

Yes, I suspect this might be a contentious post, however, I think its a subject that affects many people these days with offsite and offshore working habits on the increase. On a number of occasions, I have heard arguments that remote teams can work very well together and the reason I bring up this topic is to gauge opinion out there. There is no need for the sake of this argument to even consider language or cultural barriers, I would like to keep the discussion purely down to the communication aspects geographically dispersed teams.

It is harder to communicate with individuals or parts of a team who are dispersed - when I am deeply engrossed in a problem, I want to be able to quickly convene and discuss the items round a whiteboard or go to Starbucks - where many great ideas have been born. I am prepared to concede that some of the items listed below are due to my lack of understanding of how to make them work - I genuinely want to know if folk out there think it can succeed. Indeed can we call it agile if a team is not collocated?

Following are a few of the things I consider potential problems with distributed teams -
1. Try to call them - they can easily ignore the call
2. IM them - can easily be ignored
3. Post on a message board - delayed communication
4. Video link - can easily be switched off, ignored
5. Can't easily share ad-hoc conversations
6. Much harder to pair up for work or coach people
7. Tends to lead to less of a team and more of a rivalry culture
8. Much harder to use low-fidelity, low-tech approaches such as information radiators and story cards
9. Almost any form of agility puts the customer at the center - if the customer is only on one site, how can the people working away from that site be working in an agile manner?
10. Phone and video systems are prone to technical problems

My feeling is that all things being equal, a completely collocated team using big visible charts and other low-fi practices stands a greater chance of success than a distributed team who are forced to use hi-tech, computerized and error prone forms of communication. Simple techniques such as whiteboards, post it notes, index cards and flip charts help to short circuit communication and get the point across in a faster, simpler and less ambiguous way.

I have persevered with many different techniques with offsite personnel and non quite seem to fit the bill for me - maybe I am just not trying hard enough. Perhaps over time its possible to learn to be much more effective and communicate as well using complex communication mechanisms as we do face-to-face.

Thoughts?

Agile Acceptance Testing

If you haven't already, read the post on infoq about automation test tooling. This is an interesting post and I think there is a lot more mileage on this subject.

In a project I have been involved with recently, we employed a commercial heavyweight record/playback style of acceptance test tool and something did not smell right about using this solution, but I did not give it enough consideration at the time. I don't want to repeat points in the original post by Elisabeth Hendrickson but rather try to add or confirm Elisabeth's findings for myself.

If user interface elements are changed, the team is always tempted to recreate all their tests, why? The majority of test code should remain unchanged, but the perception is that the tool provides all the code via test generation and guides people towards simple regeneration, and hence longer turn around and less of the refactor quickly mentality when the user interface changes. In the acceptance testing world, there is still a large contingent of practitioners who tend toward manual testing and there are far too many who do not understand how to use scripting languages such as python or ruby which both offer a simple approach to writing tests - either manually or via the use of a library such as PAMIE or WATIR.

Unfortunately I cannot think of other great reasons why I see these scenarios as particularly bad, its just that this activity does not seem able to keep up with the rate of development and that just isn't right. I want to see very small specific pieces of test artifacts built alongside the feature, and many of these tools seem to bring a bunch of extra baggage along that just seems overkill.

Sunday, May 4, 2008

BPM Frameworks

Business process modeling is something I always thought of as simply a knowledge sharing exercise that takes place amongst a group of folk who simply want to understand either how things operate in an organization, or how they would like things to operate - I guess there are thousands of shades of gray in-between.

Back in 2003, I began working on a project where a specific type of technology was employed where the programmer used business flow charts to actually build software. This particular product was supplied by a major provider of application server software, but was by no means unique to them. 

During that project, I had a problem reconciling my understanding and beliefs on system construction and this BPM/code generation model. I have often thought back to this project and struggled with it ever since, and I would like to hear from others who have experienced this feeling.

It just didn't sit well with me because I like to believe that objects are a reasonable way to model to world in order to understand what a business wants - but I am willing to accept that I might be completely wrong here (if there is a right or wrong answer). However, I temper this last statement with the fact that I worked with a few other good people, all of whom also had some very serious reservations concerning the viability of such approaches to solving problems.

Since it was some years since I last tried to use this approach to building software, I reiterate that I feel I am not as qualified those who have more recently been through this, so please let me know your experiences. I find it hard to put into words some of the reasons why this way of working seemed so alien and ineffective to me, but here goes.

1. Modeling only in terms of the dynamic aspects of a business flow precludes the static view of the system which is a very powerful tool to allow us to consider relationships between things in the problem domain. Yes, we can do this a separate exercise, but (certainly at that time) there was no mechanism to tie this view of the world with the strictly flow chart oriented view.

2. This approach led to lots of code duplication because no real world objects could be generated using a purely dynamic view of our business world.

3. One of the arguments for introducing such tools was that less experienced developers could produce working code less expensively. Actually the converse was true. With good, experienced developers working on the project, we struggled to deliver working software, simply because of the scale of complexity involved. Many mechanisms did not work out of the box and lots of tweaking was required by very smart people to do even the simplest of operations.

4. Another argument was time to market. Due to the largely visual tools, it was claimed that time to market could be reduced, because developers could be many times more productive. Just because tools are visual doesn't mean that things can be produced more rapidly. 

At the time I felt that viewing software as simply flow charts was not taking the many different viewpoints of software construction into account and that the sheer complexity of such tools (even though I don't think they have to be so complex) is actually a developers worst enemy. 

When you put good developers on a problem and they struggle, I know something is wrong. Non-developers would have quickly given up in desperation. Call me cynical but I really saw this a nasty marketing exercise - convince me I was wrong.

Saturday, May 3, 2008

TDD and User Interfaces

This is more a discussion point than me being my normal opinionated self. I buy into the TDD/BDD thing in a big way - I believe in it- although I would not claim to be as proficient as I would like to be. There are only two options -

1. View a UI as a thin layer on top of the code that matters and therefore don't bother doing anything, its a fast changing, disposable asset
2. Treat user interface elements as first class units and find a way to test them

Personally, I'm not sure I can buy into point 1) as I believe the user interface is every bit as critical to the application as any other part, however, test driving domain code can lead to design improvement, can we gain similar benefits for user interfaces? 

Automated acceptance tests should be the norm in almost any project (i.e. I can't think of any exceptions), but can/should we unit test user interfaces or pieces/components of the user interface?

I really don't know what the right answer should be (if there is one) for this and I would love to hear from people on this subject.