The notion of SHEARING LAYERS is one of the centerpieces of Brand’s How Buildings Learn [Brand 1994]. Brand, in turn synthesized his ideas from a variety of sources, including British designer Frank Duffy, and ecologist R. V. O’Neill.
Brand quotes Duffy as saying: “Our basic argument is that there isn’t any such thing as a building. A building properly conceived is several layers of longevity of built components”.
Brand distilled Duffy’s proposed layers into these six: Site, Structure, Skin, Services, Space Plan, and Stuff. Site is geographical setting. Structure is the load bearing elements, such as the foundation and skeleton. Skin is the exterior surface, such as siding and windows. Services are the circulatory and nervous systems of a building, such as its heating plant, wiring, and plumbing. The Space Plan includes walls, flooring, and ceilings. Stuff includes lamps, chairs, appliances, bulletin boards, and paintings.
These layers change at different rates. Site, they say, is eternal. Structure may last from 30 to 300 years. Skin lasts for around 20 years, as it responds to the elements, and to the whims of fashion. Services succumb to wear and technical obsolescence more quickly, in 7 to 15 years. Commercial Space Plans may turn over every 3 years. Stuff, is, of course, subject to unrelenting flux [Brand 1994].
One of the first treatments of application architecture and design patterns that I ever read was the Foote and Yoder classic “Big Ball of Mud”, from which the quote above comes. It, along with some unsavory characters on the VISBAS-L mailing list, fed my growing interest in the discipline of software architecture. Like many, I at first thought of it as just an anti-pattern. However, as the authors noted:
Some of these patterns might appear at first to be antipatterns [Brown et al. 1998] or straw men, but they are not, at least in the customary sense. Instead, they seek to examine the gap between what we preach and what we practice.
This was an eye-opener. In order to build (and maintain) good systems, one needed to understand how dysfunctional systems evolved. A poorly designed system obviously leads to trouble. Failure to manage change is just as dangerous. Quoting again from “Big Ball of Mud”:
Even systems with well-defined architectures are prone to structural erosion. The relentless onslaught of changing requirements that any successful system attracts can gradually undermine its structure. Systems that were once tidy become overgrown as PIECEMEAL GROWTH gradually allows elements of the system to sprawl in an uncontrolled fashion.
If such sprawl continues unabated, the structure of the system can become so badly compromised that it must be abandoned. As with a decaying neighborhood, a downward spiral ensues. Since the system becomes harder and harder to understand, maintenance becomes more expensive, and more difficult. Good programmers refuse to work there.
This understanding of the danger of chaotic system evolution, coupled with Brand’s notion of Shearing Layers, points the way to avoiding the Big Ball of Mud pattern. Structuring system designs using the principle of separation of concerns into cohesive layers that communicate in a disciplined manner, AKA Layered Architecture, can be used to prevent and/or correct system decay. Ideally, the initial design of a system would incorporate these principles, but it is even more important that they be used to manage change as the system evolves.
There are many variations on the theme, such as Alistair Cockburn’s Hexagonal Architecture, Jeffrey Palermo’s Onion Architecture, and Microsoft’s Layered Application Guidelines, to name just a few. My own style (to be covered in a future post) is similar to the Microsoft model, with some differences. All share the common features of separating presentation, business (process), and data access logic.
Using a layered approach has become increasingly important over the years as the scope of applications has expanded. Applications that were once just a web site fronting a database have expanded to include a variety of additional front ends such as smart clients, web parts, mobile sites, and apps (often for multiple OSs), as well as services for use by third parties. Additionally, many applications are dependent on not only their own data store, but also integrate with other systems as well. A layered approach allows for managing this component proliferation while minimizing redundancy.
Some additional advantages to structuring an application in this manner are:
- Promoting flexibility in deployment: Components grouped in logical layers can be composed in different physical tiers based on the needs of the situation. For example, a web application may combine all layers on one tier (data persistence, of course, still residing on a separate physical tier). A SharePoint web part, smart client, or the mobile apps may be distributed across multiple tiers (business and data access, exposed via a service facade, sharing one physical tier).
- Enabling dependency injection: Layers provide an excellent point for making use of inversion of control. For example, the business layer could make use of any one of multiple data access layer implementations (based on the underlying database product) in a manner transparent to it, so long as those implementations shared the same interfaces.
- Enhancing unit testing: The ability to unit test layers is similarly enhanced in that mock objects can be injected to replace dependencies of the layer being tested.
Just as you wouldn’t buy a house that needed to be demolished in order to change the furniture, you shouldn’t be stuck with a system that must be virtually re-written in order to make relatively modest changes. Change happens; architecture should facilitate that.