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.