Getting the right context is one of the earliest activities of the development cycle, and the one that has the greatest potential to cause serious problems if it is done wrongly. Unfortunately, the literature gives too little space to precise context setting, and sadly, imprecise contexts have the effect of causing the wrong, or an incomplete, system to be built. By setting the right context, the delivered product has greater user acceptance, as it fits neatly into its operating environment. There are a few conventions for setting context, that if followed, always result in a significantly improved product.
Let me start with a quote:
"The form is the part of the world over which we have control, and which we decide to shape while leaving the rest of the world as it is. The context is that part of the world which puts demands on this form; anything in the world that makes demands of the form is context. Fitness is the relation of mutual acceptability between these two. In a problem of design we want to satisfy mutual demands which the two make on one another. We want to put the context and the form into effortless contact or frictionless coexistence." -- Christopher Alexander: Notes on the Synthesis of Form.
In our case, the form is the solution, or product that we intend to build. I will assume that this solution includes some software, and it may, and often does, include human activity and other devices.
To set the right context, it is necessary to think of the solution, and its surrounding environment. It is the fit with this environment that largely determines the acceptance and usability of the delivered product. I propose that we think of this as an interaction between domains. Consider the part of Alexander's quote that talks about the context being anything that puts demands on the form. He is saying that we have to look outside the solution domain to find all the influences, because some of the influences are the other domains that interact with our solution domain:
Initially, the interfaces between the domains are less than clear. While we know what the other domains are, we do not know precisely where the boundary lies between the solution domain and the others. We have to define this quite precisely before we can ever get the correct requirements.
The most straightforward way of finding the true interfaces between domains is to determine the characteristics of the domains. Each different type of domain has inherently different characteristics for its interface, so by knowing the type of domain, we can get a clear picture of the interfaces between it and the solution. The reason for needing to know this interface is to precisely determine the extent of the solution that we must provide.
We can characterize the interaction of the solution domain with the other types by using a context diagram like this:
The illustration shows the solution domain interacting, or at least exchanging data with, other domains. I have not named the data flows to and from the solution domain, but shall as the example develops. Naturally there could well be more than one of each type of other domain, and all types of domain are not always present. Data and control flows are used as this gives us a very precise definition of the interface between domains, and tells us exactly how much of each domain we have to study. I shall explain this.
The solution domain is an obvious starting place. This is the product that we intend to shape. A definition of the solution domain is relatively straightforward: The solution domain is anything for which we have been given a charter to change, to design or to build.
It is at this point that a major misunderstanding often occurs. I have said that the solution domain must include anything that we have a licence to change, build, or make some use of in our final solution. This is not just the machine or the software - a mistake that will inevitably lead to building an automated product that does not fit with the surrounding work practices. Almost all commercial projects have human activity as part of the solution, simply because commercial ventures usually do not allow outside humans, such as customers, come in direct contact with our software solutions. They insert a human between the customer and the software. Even where the humans are not filling this go-between role, such as when customers use an automated teller machine, there are still humans involved in the solution. These are the people who load, empty, maintain and inspect the ATM. If these humans (or indeed any other device that we may bring into play) are not regarded from the outset as part of the solution, then it is possible to build a product that will fail, as it cannot be serviced by the attendant humans.
In other words, the solution domain is made up of other domains. For example, this is the context diagram for an Order Processing system, a fairly typical commercial solution domain. This solution domain is consistent with my earlier definitions, as it contains all the devices that have to be changed or built to satisfy the solution. Note that the computer is only part of the solution. It also needs people to open the mail, discard the incomplete or bogus orders, key in the data, and so on. The people have to be trained to their new tasks, the software has to be built, and possibly the computer has to be bought. It is only by including all these devices and activities in the solution domain, that the system developer will understand enough to build a suitable end product.
Now let's go back to our objective of having a product that fits with "effortless contact or frictionless coexistence". To achieve that we must not only understand exactly what the solution domain must do, but how the solution domain interacts with its surrounding domains. It is this interaction that determines the precise boundaries of the product that we are about to build. So if this product is to fit into its context, we must look outside the solution domain, and understand how the other domains put demands on it.
The autonomous domain behaves in ways that our solution domain has no control over. In other words, autonomous domains are willful, and our solution cannot expect to change their behavior. Nor is it the intention of the solution domain to change that behavior. The autonomous domain communicates with the solution by sending or receiving data. The arrival of the data from the autonomous domain is unpredictable. So is its reaction when our solution sends data to it.
The autonomous domain is some external body, such as another company, a government department, or anything that acts independently of the solution domain, but has demands upon it. The demands are expressed by the data that flows to or from the autonomous domain. It looks like this:
We need to understand the content, format, delivery medium and frequency of the incoming and outgoing data flows. Note that data flows are the only form of communication. That is, the connection is not truly an interaction, but happens from time to time. We (the developers of the solution) cannot change the interface without negotiation.
The autonomous domain is not changed by the interactions with the solution domain. The autonomous domain decides for itself whether or not to change itself. In the example shown, the solution domain is a ticket dispenser for an underground railway, and the autonomous domain looks after traffic on the rail network. The ticket dispenser gets information about the state of the network, and displays this for travellers. This Network Announcement is sent at the convenience, or discretion, and at a frequency determined by the autonomous domain. The solution has no control over its arrival. The Traffic Report may have an effect on Rail Network Management, but whether it does or not is decided by the the autonomous domain, not the solution domain.
The interfaces between these two types of domains are pre-determined. In this situation there is likely to be an existing contract between the two domains for an interchange of data. This means that where our solution domain interacts with an autonomous domain, we define the boundary of the solution by defining the interfacing data flows.
Benign domains are changed by external agents. They do not change their behavior as a result of receiving data from the solution domain, but can be relied upon to behave predictably when called upon. A benign domain might be a database belonging to another domain, an operating system, or any system that provides a documented, and predictable, service to our solution domain. We may access the benign domain, store data in it, or request some service from it, but the behavior of the benign domain does not vary as a result of our attentions. In this example, the solution is asking the Fares system for today's fare structure. The fares are changed regularly to give the railway flexibility with its pricing of tickets, and to make reduced-price offers available for special circumstances. Thus the ticket dispenser must ask on a daily basis for today's fares.
The interface between the solution and benign domains is similar to that of the autonomous domain. The difference is that here we are more concerned with the immediate response we get from the benign domain. As the benign domain is responding to the data flow sent by the solution domain, the actual service preformed is interesting. The solution domain must know what service is provided, and what parameters it must supply to receive that service. So once again, by defining precisely the data flows between the two domains, we define the exact responsibilities of each of them. Thus we understand the interface with the benign domain, but not its functionality, apart from knowing it as a black box.
Biddable domains can be expected to change their behavior within reason. They will cooperate with the solution, provided that the cooperation is in the interest of the biddable domain. For example, if our solution domain was an automated teller machine, then the bank's customer is a biddable domain. The ATM can ask the customer to perform certain actions, and as long as those actions are more or less beneficial to the customer, the ATM system can expect the customer to perform them. In this example, a traveller buys a ticket from the solution domain:
The biddable domain requires more of an understanding. We must not only understand and document the interfaces, but also understand the domain's behavior well enough that we can reasonably predict its response to signals or data sent from the solution domain. The interface with a biddable domain is likely to be more complex because it is likely to be more dynamic. This time the solution domain sends and receives both data and control signals. (The control signals are shown on the diagram as dotted arrows.)
Note the nature of the biddable domain: we can predict its behavior within reason; and the designer of the solution domain can determine the data and control interfaces. This nature makes it quite different from the autonomous and benign domains. Now there is no pre-existing contract for the interface, and the behavior of the domain can be changed or influenced to some extent. The problem now shifts from defining an existing condition to designing a desired state of affairs - designing what actions are to be done by the solution domain, and what are to be done by the biddable domain.
Finally, we can turn our attention back to the solution domain. Now that we have defined and understood the nature of the interfaces between this domain and the others, the task of defining the functionality and properties of the solution domain becomes a lot easier. We could simply say that the solution domain is simply the transformation of all the inputs into all the outputs. However it is more complex that that, as some of these transformation have to use services and properties that are internal to the solution. However, by setting the correct context, we make it possible to build the right product.
The context is made up of the solution domain, and the interfaces to any interacting domains. It also includes as much of the external domains as we need to study in order to understand the interfaces. In the illustration, the shaded area indicates the extent of the context. We cannot be precise about how much of the external domains have to be studied, but it must be enough of them to be certain that, given the type of domain, we understand their motives in sending data to our solution domain, and understand how they use the data that is sent from the solution domain. In the case of the biddable domain, we need an almost complete understanding of its behavior in regards to our solution domain. For an autonomous domain, understanding the interfaces is possibly sufficient.
To develop a successful solution, we have to understand everything within the context. These notes are intended to help you to determine just how far the context extends. Only by understanding its extent is it possible to design a product that fits, without gaps or friction, within its context.
A domain is a subject-matter area of study. For example, we can have a domain that is a business area, such as air traffic control, banking, engineering, insurance, or any other area of human activity. A domain can also be technological, and cover subjects such as telecommunications, user interfaces, networking, and so on. In essence, the domain can cover whatever area we find convenient for our study.
Domains are bounded by having all their processes, data, objects and artifacts behave according to rules that are set by the domain. Thus the study of domains, or domain analysis, determines the generalized characteristics of a domain.
Data Flows and Domain Boundaries. I strongly suggest that data flows are the best device for precisely defining the boundaries of the domain. Why is it important to define these boundaries? Let's go back to the objective of setting the context. We are trying to achieve a frictionless fit between out solution, and its surrounding context. We can only do that by knowing exactly where one system starts, and the other ends, and that the starting and ending are complementary.
Each time a process occurs, it transforms the incoming data into the outgoing data. This is hardly earth shattering stuff, but consider the consequences. If each process changes the data, then by defining the content and state of a data flow that connects the processes, we have effectively given a location to the process that made that change. In other words, if a data flow is in a certain state, then we must know the location of the process that put in into that state. In the case where the data flow is the interface between domains, by defining the state and content of a data flow, we are defining the meeting points of the concerned domains.
Note that the name of the domains is not a precise definition of where its boundaries lie. Very few domains represent the entirety of the real world subject matter area. For example, if I have a domain called "Air Traffic Control" does it include the activity of paying the controllers? Does it include the software development activities needed for ATC? Does it include the manufacture of the ATC hardware? The controllers break rosters? And so on. Usually any domain, or system, is an abstraction of the subject. So the name of the abstraction is very imprecise. To be precise about the extent of the domain, we need to publish and define its data flow interfaces. This way we define which processes exist inside the domain, what data is needed to support the processes, and ultimately what behavioral properties are needed for those processes and data.