Architecture is Dead -- Long Live the Architect Neil Harrison Avaya Labs nbharrison@avaya.com 303-538-1541 To begin with, we need to understand what software architecture is. We also need to understand its purpose, and how it influences, and is influenced by, process and organization. What is Architecture? At the outset, let's get one thing straight: The bits don't care. Architecture is for humans. We use architecture to help us implement, maintain, and perhaps most importantly, to understand the software. Architecture has two main pieces. The first is the vision of the system, and the second is partitioning of the problem. The Vision: When more than one person works on a system, it is important -- no, critical -- that they be pointed in the same direction. I call this Unity of Purpose (PLoPD2). They need to know what the overall goal of the software is, perhaps who the enemy (competitor) is, and the overall approach to the implementation. Note that this has to be short, so people can easily grasp it, but it must be long enough to have substance. Eric Evans (Domain-Driven Software, to be published) suggests a single page for it (Domain Vision Statement.) XP misses the boat with Metaphor. First, it's too short. It MIGHT be all right for small projects, but it is insufficient for medium or large projects. Second, people don't understand Metaphor itself -- the fact that Kent Beck has to use a keynote speech to try to describe it is proof that it doesn't work. Fortunately, this is easily remedied: Agile projects should do architecture; in my experience, most do. Partitioning: This is the heart of architecture, while the vision is the soul. And the heart is usually where the bulk of the work lies. In order to partition the system effectively, we need to know both what is partitioned, and why it is partitioned. Do we partition the problem space or the solution space? We mainly focus on partitioning the solution space, but it really is both: Partitioning the problem space is generally part of analysis, but the architect must work with the problem space to create the proper partitioning. In this sense, the architecture is a bridge between the two spaces. What are the purposes of partitioning? Obviously, the first is to create the aforementioned bridge. This means we make sure that the requirements (problem space) can and will be satisfied by the solution. The second purpose of partitioning is to help people comprehend the system. In order to make this work well, it is necessary to give each partition a name that describes what it does. This creates a high context language for conversation and comprehension. The third purpose is to divide the work among the implementers. They need to be able to work without stepping on each others' toes. This means that partitions must serve to hide information from each other (see Parnas' works). This is really important. Finally, partitions, if done correctly, make maintenance easier. So the system must be divided so that later changes can be implemented by changes in only a few related modules. Bu what if the problem space is ill-defined or changes during development? This is why XP eschews architecture, and why XP advocates architecture that emerges through development. This does not eliminate the need for architecture. In fact, the opposite is true. A sound architecture can actually make XP or other agile styles of software development work better. This is particularly true of medium and large projects. It works like this: Remember that one of the main purposes of partitioning is to allow parts of the system to change without affecting the rest of the system. Therefore, if some aspect of the problem space is not well defined, the probability of it changing is high. Therefore, it makes sense to partition it away from the rest of the system. Likewise, one can make judgements about the liklihood of all features changing, and partition them accordingly. For example, you are building a system, but the human factors engineer is still working with the user to come up with a good scren layout. Obviously, one would separate the user interface from the rest of the system. Naturally, one must define the interface between the user interface code and the rest of the system. If, however, the user doesn't yet know _what_ data needs to be displayed, then one might need additional partitions to hide the data itself from most of the rest of the system. If you find yourself refactoring, a sound architecture is valuable. It helps guarantee the limited scope of changes, thus simplifying regression testing. Some refactoring may occasionally cross partitions, causing changes to the architecture. Such changes should be relatively rare, but you should be able to fall back on system level regression testing to verify the correctness of such changes. The architect's role follows from the purposes of architecture. The architect usually plays a major part in creating the vision of the system. Ongoing, the architect is the keeper of the flame, ensuring that people understand the vision. The architect does most of the partitioning. In this role, the architect must figure out how to span the problem and solution spaces. The architect needs some understanding of what things are likely to change: it need not always be detailed knowledge; in some cases, a gut feel is sufficient. Ongoing, the architect helps maintain the integrity of the partitioning so that it remains useful. Note that the architect must also do some implementation (Architect Also Implements); understanding of implementation issues is necessary in creating a viable architecture. In summary, there should be no conflict between agile development and architecture. They can -- and should -- complement each other nicely.