Thursday 22 November 2007

Challenging your own views

Yesterday, I read this interview on The Register with Adam Curtis about how mainstream media are failing to take a lead by paying too much attention to bloggers.

It is quite long (as these things go) but it provoked several trains of thought in me that were not directly the subject of the piece.

One of the themes in the article is the existence of different groups (of bloggers) with fixed viewpoints who refuse to listen to any opposing or alternative viewpoints. The article takes this as a reason why the mainstream media (such as the BBC) choose to tread a middle path between opposing groups rather than trying to form their own view.

My personal lesson from this is the weakness of being too blinkered in ones views. If you hold strong views then it is very easy to keep reinforcing them but in a technical and management arena it is useful to chalenge your own views occasionally. I am in some ways an archetypical 'Guardian' reader and I can be comfortable reading newspaper articles and columnists that agree with me but too much of that breeds complacency so I make a point of reading 'The Independent' quite often to get some opinions that I don't automatically agree with. I have tried reading newpapers with views further away from mine and it is much more difficult to critically assess their views - get too far to the right and I just get angry...

In technical areas, I often take part in discussions with engineers puttng forwards views with which I disagree. In some cases, their view is not that controversial but it is simply not what I wanted to hear because I came to the dscussion with a proposed solution of my own. In other cases, I really do disagree with their view but I make a point of hearing them out and trying to see the value in it, despite my biases. This can require some emotional effort to be patient and objective, particularly when we are working under time pressure or when the engineer presenting his views is doing so clumsily, but I find enough occasions when there is value in the other point of view to keep making the effort.

Wednesday 24 October 2007

Why do Managers behave like idiots and why are Engineers so obstructive ?

All engineers have anecdotes about when one or other manager behaves in an idiotic manner, making decisions that are obviously stupid. Often, the more senior the manager the more frequent the bad decisions and the more serious the outcome.

Alongside this, all managers know that getting engineers to do something new or different can be frustrating to the point of apoplexy. Engineers seem to have an innate desire (and skill) for finding objections and reasons why a proposal will not work.

I suggest that both of these problems are caused by the different environments and needs of managers and engineers. My starting point is to acknowledge that both managers and engineers tend to be highly intelligent and highly motivated – neither group is stupid or deliberately obstructive.

Managers have two problems that are relevant. The first is the scope of information that they need to handle. The second is the effect of friction in any organisation.

By information scope, I mean the range of information for which a manager is responsible. Even a quite junior manager is likely to responsible for a number of projects and the more senior the manager the wider the breadth of the organisation that they are supposed to know all about. This means that a manager cannot possibly know everything about all the projects etc. under their control. This does not stop more senior managers expecting instant answers to random and detailed questions. When necessary, a manager can learn all about one area (and engineers may be surprised at the speed at which a good manager can filter and absorb information) but they cannot learn everything and maintain that knowledge.

The information scope problem means that a manager will tend to have to make decisions based on partial information. The more senior managers get their information from their subordinates so their information is second-hand as well as partial.

The concept of friction comes from Clausewitz and refers in this case to all the factors that make even the simplest organisation task difficult. Clausewitz ascribed friction to the physical danger of war and the physical challenges. Most organisations do not have this level of danger but communications difficulties, conflicting priorities and natural resistance to change all make it unexpectedly difficult to carry out projects or to make changes. This means that any successful manager has to be a highly motivated problem solver. One aspect of such behaviour is an ability not to be put off by minor obstacles. If a manager stops to re-think the plan whenever somebody objects then they will never succeed. In contrast, if they ignore or override objections they may hit problems but they have a better overall chance of success. Of course, the really good managers have to decide which objections are serious and which can be safely ignored.

One side effect of the information scope and friction problems is that managers have to be able to look at the big picture without getting bogged down in minor details. Oh, and they are commonly under time pressure which can make them impatient with unnecessary details.

Turning to obstructive engineers, we can see that a good engineer needs to care about detail and needs to learn everything relevant about their subject or immediate problem. As engineers tend to work directly on their problem, they may be less affected by organisational friction (apart from the friction in getting budget or resources) – they tend to be hands-on.

When engineers discuss technical problems, they need to have a shared knowledge base that can be detailed. Therefore, they may have to provide a large amount of background information in order to present a problem or ask a question.

If an engineer ignores an inconvenient problem for reasons of expediency then the problem is unlikely to go away. It is more likely to return when least expected but bigger and uglier than before. Therefore, engineers tend to focus on problems as they find them and are uncomfortable moving on until they are convinced that the problem is solved (or at least can be solved for a reasonable cost).

To a busy manager, engineers are people who keep bringing up problems, describe them in a long-winded way and need constant ‘motivation’ to keep them moving forwards.

To a conscientious engineer, managers are ignorant people who don’t have the patience to understand what is really going on and who prefer to deal with problems by ignoring them.

Tuesday 12 June 2007

Thoughts on interviewing software engineers

Over the weekend I came across this blog entry.
http://blog.pmarca.com/2007/06/how_to_hire_the.html

I do a lot of interviewing and I am very aware of how difficult it is to make an interview effective so I am always interested to read about interview techniques for software engineers.

Mostly, these focus on problem solving but I distrust these. I do have a collection of interview problems, some based firmly in software engineering and others more abstract, but I have tried them all myself and I don't believe that the ability to solve arbitrary problems under interview conditions is a good indicator of ability.

To be more accurate, I don't believe that the inability to solve one particular problem under interview conditions shows that an engineer is incompetent in general.

Tuesday 29 May 2007

Code Generation 2007

I had the pleasure of attending the Code Generation 2007 conference held at Homerton College, Cambridge on the weekend of 19 and 20 May (actually, it started on the Friday but I was unable to attend until the Saturday). I went because it was some years since I looked at code generation and I wanted to see how the state of the art had changed. The presenters were very competent, academically sound but grounded in real life and the conference was friendly and well run (thanks to Software Acumen).

I don't think that I'm going to be able to apply much in the way of code generation to my day job but it was a very well run conference and certainly thought provoking. I picked up a couple of books and I have dug out a couple more from my shelves.

I didn't find much new in the generic modelling and code generation techniques although it was good to have my views checked by comparison with current best practices and I will take a long look at how to preserve design intent at some time. Krzysztof Czarnecki of the Univ of Waterloo in Canada was notable in this area. The area that were new to me was the coverage of Domain Specific Models (DSM) and Domain Specific Languages (DSL).

Two good sessions on DSMs were run by Juha Pekka Tolvanen of MetaCase and I was particularly struck by the Symbian OS S60 application generator. Juha Pekka was very good at identifying the success factors for a DSM to avoid misplaced use.

Monday 12 February 2007

Nice short article by Matt Stephens about individual differences

The article is on The Register Developer site -
Non-Humans need not apply.

In it Matt makes a case for treating software engineers as individuals with unique skills and characteristics as opposed to the generic 'resources' that MS Project thinks they are.

I can also recommend reading up on Belbin's team roles, if only for the sake of self-awareness.

Sunday 11 February 2007

Estimating and why it is so hard

In this essay I want to consider the topic of estimating in software development. As any software engineer knows, there is a constant pressure to provide estimates for how long a task will take and it is notoriously difficult to come up with decent (by which I mean reasonably accurate) estimates.

In order to understand this, I want to consider what an estimate is, what the limitations on an estimate are and to touch on some of the techniques that can help.


What is an estimate?
An estimate is a prediction of the future. The most common form of estimate required in software engineering is how long it will take to do a task. Depending on the context and the sophistication of the organization, the estimate may be in terms of man-days or elapsed time and may be loaded to some extent.


Why is estimating hard?
Predicting the future is hard in general. If it was easy then stock market analysts and astrologers would be out of business. In the field of software engineering, some tasks can be routine and some tasks are novel. The difference is crucial - if you treat all tasks as novel then it can be impossible to move forwards but if you treat all tasks as routine (often the assumption) then you fail to take into account the real difficulties and you are almost certain to come badly unstuck.

Routine tasks are those that we have done before and that we have a reasonable chance of successfully doing again. They are unlikely to be totally routine but the probability of surprises is low.

Novel tasks are those that involve a high level of creativity or problem solving. We don't know how to do them before we start and so our prediction of how much work will be involved or how risky they are is not likely to be accurate.

There is a host of techniques to help with estimating routine tasks. These have been analyzed extensively and are covered by books and training courses. It is still possible to make mistakes but the probability and the consequences are manageable with some planning.

There is a much smaller range of techniques to help with novel tasks but there is some hope.

Limitations to Estimating
A naive view of estimating is to expect an estimate to be a single figure that should be more or less accurate. For example, if an engineer estimates that it will take five days to program the Wurlitzer component then we might expect the Wurlitzer component to be complete five working days after he starts. if it takes six days then we will view that as a 20% over-run and so on.

The first catch is how well we have defined the task that has been estimated. Does the task include code review and rework? How about unit or integration testing? How about documentation? This type of problem can be overcome simply by taking pains to be clear about the task definition and the easiest way to achieve this is to work out (and publish) a set of organizational norms so that engineers and project managers know what they are talking about without having to argue about it or write lengthy project documents.

The second catch is is that a single figure gives no measure of the risk. If five days is the most likely time for completion then what is the probability of going over by one day, or two etc. A task that has a likely time of five days but a worst case of ten days is significantly different from one with a likely time of five days but a worst case of 20 days. A standard way to represent this is to use 3-part estimates. For each task, estimate the time taken in the best case (if nothing goes wrong), the likely case (assuming normal levels of disruption and problems) and the worst case (assuming lots of problems). As an aside, the real worst case is always infinite, what we are really after is a 95% estimate; a figure within which we expect to finish in 95% of cases.

There are formulae to combine the best, likely and worst case figures to give a single figure for planning purposes but I find the worst case estimate useful simply because of the thinking that it triggers. If you can get an engineer to avoid adding a standard percentage to all estimates to get the worst case then the interesting tasks are those for which the worst case is much larger than the likely case. Look at these tasks more closely to see if there are risks or uncertainties that could be eliminated.

The other value of 3-part estimates, apart from helping to identify risky tasks, is that it makes explicit that there is a margin of error on any estimate - it is not a guaranteed figure. It can be interesting to consider how the margin of error changes over time. Theoretically, the margin of error is linked to the degree of knowledge or uncertainty about a task

Initially, we have a very limited amount of knowledge about a task (certainly if it is novel). As we progress through the task (or through other tasks that affect it), we gain more relevant knowledge and the margin for error should decrease (when the task is complete the margin for error should be zero!). This is why I believe strongly in re-estimating during a project and a task to get better estimates as we go along.


Estimating routine tasks
I will not spend many words on this subject because there is such a rich body of work already available. The key techniques are to use historical data and check-lists and to identify causes of variability. Measures of task size such as function points or lines of code can be a valuable starting point and measures of variability such as engineer experience or the complexity of the other components to be interfaced with can be useful.

Even with routine tasks, estimates will never be 100% accurate. Unforeseen problems and variations can trip up the most experienced engineer. However, with some effort, the 3-point estimates can cover most of the tasks.

If a project includes a mixture of routine and novel tasks then it is worth minimizing the risks on the routine tasks just on principle but the majority of the uncertainty will come from the novel tasks.


Estimating novel tasks
With novel tasks, it is difficult to predict the work based on history so we need an alternative approach.

The only real way I know to approach a novel task is to do some up-front design. This is aimed at eliminating some of the areas of uncertainty and trying to break the task down into smaller parts that are more easily understood. It is important to understand that you need to do some work before you can start to come up with the estimate. It is not reasonable to ask for an estimate for a poorly understood task without allowing for some analysis.

The trick is to decide how much analysis is required before coming up with the estimate: too little and the estimate will be dangerously unreliable, too much and the work will never start.

Depending on the types of uncertainty, you might try prototyping but this does not replace the need for design work.

Sunday 28 January 2007

What is a Software Architect?

This essay discusses the tasks of a Software Architect and what properties and skills an engineer has to have to fulfill the role.

The headline skills required are Design and Communication with some secondary Project Management skills.

Communication

A software architect has to be able to communicate with a wide range of people including customers, suppliers and partners as well as within the development team.

As in any situation, if you want to communicate effectively with somebody you need to understand their needs and their point of view. Therefore, the software architect needs to understand these different groups well in order to be successful.

This communication ability can be difficult for some software engineers to acquire, particularly if they have spent a lot of time in a back-office or working in specialized technology. The good news for such engineers is that this is the standard stuff of management training and these skills are well worth acquiring in their own right.

There are several reasons why a software architect needs to communicate with various groups:

  • the architect needs to talk to the customers to find out their use cases and their requirements. This also requires that the architect be able to understand their business so more management skills come into play.

  • The architect needs to present a proposed solution to customers. Even if there are sales or marketing professionals involved, the architect will be needed to answer technical questions and he or she may end up as the external face of the project or system.

  • The architect needs to communicate within the team to ensure that everybody understands the overall design and what is needed.

Representing the chosen solution in this way requires that the architect develop good 'people skills'. An engineer who is not a 'people person' will struggle to be a good software architect.

Design

It is probably obvious that a software architect needs to be skilled at software design but it is still worth stating. It is also useful to consider the additional design skills that an architect needs that designers of smaller components may not have developed.

The principal difference is in the scope of the design. Almost by definition, a software architect needs to design complete systems that may consist of a number of parts that communicate or interface with each other.

The architectural design must take into account overall performance and robustness rather than focusing on one part in isolation. This kind of overall optimization is more difficult than purely local optimization and may require some parts to be less optimized for the sake of the larger picture.

The architectural design must be heavily concerned with the split into sub-systems or components and with the communication between them. Therefore, an architect must be good at defining or finding the interfaces or protocols between the parts of the system. In general, if there is a good (or good enough) standard or protocol then it should be used rather than a newly invented one. This means that a software architect needs to be familiar with all the different protocols that may be useful.

Although the software architect is concerned with the 'big picture' design, he or she has also to be aware of the lower level design issues. This is comparable with a civil engineering architect needing to be familiar with the properties of concrete, steel, brick and glass in order to know how best to use them. If a software architect is not capable of designing the building blocks of the overall design then their design is likely to be flawed in detail (or they will need a lot of support from local experts).

This is why I think that a software architect needs to find ways of keeping their technical skills up to date. Where possible, some prototyping or hobby programming contributes to this but extensive reading is also required.

Making sure that the architectural design is of a high quality in the first place is critical but the architect also needs to make sure that the quality of the actual deliveries is maintained. This is not really a design issue but it is a technical issue and the architect is likely to be the final arbiter on whether the quality is good enough.

Project Management

In many cases the software architect will not also be the Project Manager but the architect needs to have a good awareness of project management issues and must be committed to supporting the project manager. Of course, if the architect is also the project manager (maybe with a title such as Software Lead) then the need is even stronger.

The architect needs to consider development and maintenance costs for the different parts of the system. If there are design choices then the costs are a factor alongside technical suitability.

When the project plan is under development, the dependencies and ordering of tasks must be based on technical considerations. The choice of which components to implement first (or which parts should be designed and implemented in parallel) may be based on technical dependencies or on which parts can be tested in isolation or on which parts carry the highest risk. All of these are technical questions that the architect must answer.

Once development is underway, risks must be kept under review and the project manager needs the architect to decide what is happening to the technical risks.

Within the project team, the architect is best placed to make sure that everyone knows what is going on from a technical point of view and he or she is responsible for contributing to team morale (in a positive way!). An architect who is a good leader and is respected by the team can make a tremendous difference to the success of a project. One who fails in these regards is a serious danger.

Monday 15 January 2007

What is the point of a design?

This essay explores the purpose of a design. This begins to show how multi-faceted is the term design. As a verb it refers to making plans or creating something; as a noun it refers to the plans, sketches etc. (for the sake of convenience I ignore the other meanings that don't really relate to software). The design process is the creative act but I want to focus here on the design artifacts - what might be called the design document, whatever form it takes.

I suggest that there are at least five uses for design artifacts and that these uses correspond to stages in a design and development process.

  • Design as a thinking aid

The first use of a design is as a thinking aid. Early in the design process, the designer is engaged in the pure creative act (at least that's what I claim when I am discovered staring out of the window). Although the earliest stages may take place solely in the head of the designer, some drawn or written form will normally appear quite soon. As a minimum, I will draw some form of picture just to stare at - it provides a structure on which to hang my thoughts.

With any design of real complexity there will be one or more difficult problems to solve or critical aspects to handle. Exactly what these are depends on the system but common ones include performance, robustness or complex algorithms. While attempting to solve these problems, the designer will want to draw pictures or create state or sequence diagrams to explore them and to test theories. If the problems are suitable then a partial prototype can be very useful.

At this stage, the design artifact should contain only what is needed to investigate the key problems: obvious or easy parts of the design can be taken for granted. There is no need to have a standard form or to cover all aspects of the design and the design does not have to be optimized for communication.


  • Design to support Peer Review

The second use of a design is to support a peer review of the design. Actually, I want to include both formal peer reviews and informal design discussions but I will cover the formal reviews first.

In order to support a peer review, the design artifact needs to support communication - the design concept needs to be shared with the reviewers. This is where the use of some standard or shared notation kicks-in to minimize the learning effort.

It is likely that a design for peer review will need to include at least a minimum of standard information to provide context but the emphasis should be on describing the difficult or critical aspects so that they can be thoroughly reviewed.

Of course, there is a hidden gotcha here. If the designer skimps on the detail for the parts that can be taken for granted and is wrong in their judgment then the peer review will miss these problems. This is an argument for covering all aspects of the design to some level of detail but I still believe that more effort should be expended on the aspects that the designer knows are problematical.

Because the purpose is to allow Peer review, this type of design must include more than just static pictures. State diagrams or sequence diagrams should be used to show how the design works or how it can be used.

By separating the design as a thinking aid from the design for peer review I have omitted an intermediate stage, the design as a tool for early design discussions. Wherever possible, I like to get input from other people on a design and this requires something to talk about. If you are lucky, this can be a picture drawn on a whiteboard with minimal effort. If the design is more complex (or at least the part of the design that you want to discuss is more complex) then you may need to create a more formal representation in order to get the other contributor(s) up to speed. Whichever form you choose, this is not a formal peer review so you can focus on the aspects that you want to discuss without filling in the rest. As this type of discussion is cheap to carry out, I recommend them early and often.


  • Design to define and communicate structure & interfaces

Any system of more than minimal complexity will need to be split into parts (I avoid using a term such as components because it can have specific meanings in some methodologies) for understanding, implementation and, probably, operation. Exactly what form the decomposition takes depends on the system. A Web services architecture will involve distributed processes, each of which may be further decomposed, while a stand-alone application may be decomposed into classes or DLLs.

The decomposition of the system and the definition of the interfaces is crucial to the design of a system and so a design should describe them. This type of design can then have several uses. It can be used by teams or individuals to implement the parts. It can be used by testers to implement various levels of tests. It can be used by customers of the system as documentation for using it.

Although the decomposition is essentially a static picture of the system, the interfaces will almost certainly benefit from a dynamic description such as sequence diagrams. For those interfaces that will have external customers, I like to have a draft tutorial document at this stage, even before coding starts.

With this type of design, the internal structure of the parts does not need to be described unless they are critical or difficult.


  • Design as a work description

I dislike the development process that this type of design implies. I have seen designs created to guide 'less skilled' coders but I would much rather encourage the implementers to create any additional designs that they need where the internal structure or behaviour of components is not obvious and then carry out early and possibly repeated reviews. In this way, the implementers grow in skill and ability and there is no artificial divide between designers and coders.

This approach does require more communication and reviews within the team but I regard that as beneficial.


  • Design as a maintenance guide

At this point I have jumped from design artifacts created before or as part of implementation to design artifacts required after implementation. I think that this aspect is often overlooked or misunderstood and I will expand this view below.

If a system is to have a significant lifetime then it will need to be maintained. Any designer who believes that their system will never need maintenance is lying, either to themselves or to others and maintenance can include fixing defects and extending the system for new uses. Given the likely need for maintenance it is sensible to consider what type of documentation will support it.

During maintenance we can assume that we have some other artifacts - at least the code for the system and, with luck, some working test cases. Maintaining design documents after implementation is always problematical; under time pressure, it is always tempting not to bother to update them. Therefore, we should try to keep maintenance support to the useful minimum.

If your code is well documented (hint - Doxygen at least) then you do not need to reproduce detailed API documentation but maintenance documentation should include

- an architectural overview
- interface descriptions where in-code comments are not adequate (keep the sequence diagrams)
- records of interesting design decisions (to avoid maintainers inadvertently undoing them)
- guides to expected extensions
  • Summary

The key point overall is not to assume that there is one true form for a design document and it must be created early and then maintained throughout the design process and system lifecycle. Instead, we should consider what the purpose of the design document is at each point in time and set the content accordingly.