This post is part of a series on IT consulting. It describes an approach to developing an application with the explicit expectation that its requirements will change.
The approach involves identifying areas likely to change, and then designing the application in a way that separates or isolates those areas of concern from the rest of the application, thereby minimising the impact of those changes on the rest of the application.
This separation of concerns is a design principle in which distinct features within a computer system are separated so that they do not overlap. A concern is synonymous with a feature or behaviour. It is achieved through layered design, modularity, encapsulation, information hiding, and loose coupling.
- Layered design: Layered design consists of grouping components that perform similar types of functions into layers, which in turn are organized in a stacked fashion so that components "above" a certain layer use the services provided by it, and a given component will use the functionality provided by other components in layers "below" it to perform its work.
The stacked nature of layers allows layers to be deployed in tiers. Tiers refer to physical distribution patters, in which presentation services that maintain state might be deployed to a web server, stateless business and data access logic to an application server, and the database to a dedicated data server.
Layered designs improve system performance and stability, in that layers that are identified as performance bottlenecks can be deployed to dedicated tiers and scaled out as required.
- Modularity: Modular programming emphasizes separating the functionality of a program into independent, interchangeable modules. Each module contains everything required to execute a single aspect of the desired functionality.
Modularity improves maintainability by enforcing logical boundaries between components. Consequently, a module prone to failure can be fixed or replaced without affecting other modules within the system.
Modularity also facilitates extensibility. New components can be added to the system without requiring changes to existing components, beyond configuration changes or high-order process compositions.
- Information hiding: In computer science, information hiding is the principle of separating the design decisions in a computer system that are most likely to change, thus protecting other parts of the program from extensive modification if that design decision is changed. This protection involves providing a stable interface which protects the remainder of the program from the implementation (the details that are most likely to change).
The benefit of information hiding is that it reduces system complexity, and thus increases robustness, by limiting the interdependencies between software components.
- Encapsulation: Encapsulation is a more granular form of information hiding. It means that the internal representation of an object is hidden from view outside of that object's definition. Typically, only the object's own methods can directly inspect or manipulate its fields.
Restricting access to the internals of an object protects its integrity by preventing users from setting the data of a component into an invalid state. Like with information hiding, the benefit of encapsulation is that it reduces system complexity, and thus increases robustness, by limiting the interdependencies between software components.
- Loose coupling: a loosely coupled system is one in which each of its components has, or makes use of, little or no knowledge of the definitions of other separate components.
In addition to the above, consider what changes the system might face at the design level. Business rules are easier to maintain in configuration files than in code. Be aware however, of duck programming - the rules may not be in the code, but you're still going to need a programmer to maintan them.
A good approach to mitigating changing data structures is to use a meta-data driven approach. This lets you use form designers instead of coding out your own. Further down the stack, consider using a document database, and fronting that with a relational database to maintain associations.