Architectural hoisting (original blog post)
Following architecture-centric design means that you are using the architecture to ensure a property or to achieve a quality attribute. Code can diverge from the design, often unintentionally, and disrupt your plans. We can use architecture hoisting to ensure that the code has those same properties or qualities as the design.
Architectural hoisting is the direct ownership, management, or guarantee by the architecture of a feature, property, or quality attribute. It lets developers depend on the architecture for the hoisted feature, property, or quality. This usually entails writing the application code separate from the architecture code, so the architecture has a tangible existence in the source code.
Architecture hoisting is an outgrowth of architecture-centric design, but hoisting entails localized code that you can point to and say, for example, “This code handles transaction independence.” Conversely, architecture-centric design may be seen only indirectly in the source code, or the quality may be emergent from the design. The components as designed may result in a high peformance system, but there is no one part you can point to that localizes the management of performance.
Hoisting of features is commonplace. Imagine that your system must log all access to a resource. You could say, “Everyone using the resource should log their access,” but if someone forgets then the invariant is broken. Alternately, you could encapsulate the resource behind an API that logs all accesses. Doing so ensures that the logging invariant is satisfied.
Hoisting properties or quality attributes is less common but there are some mainstream examples. An application server is software that handles runtime qualities of an application and they are often used for web applications. A developer writes an application and the application server handles running many copies of it on a single machine (hoisting concurrency) or even spreading out the copies across multiple machines (hoisting scaling). An Enterprise Java Bean (EJB) application server hoists concurrency, scalability, persistence, and transactions. In fact, an EJB application server can be seen as an improved Servlet application server that is more effective at hoisting concurrency problems.
The Eclipse framework hoists many features, properties, and qualities, such as resource management, concurrency, and platform independence. The Eclipse framework can be extended with plugins, which can be recursively extended by other plugins. Plugins must know how to load the plugins beneath them, but doing so incorrectly will break the framework’s properties. Erich Gamma and Kent Beck’s book describes how to load new plugins and still maintain the “Diversity Rule” property (Contributing to Eclipse, pp 72-73, 2003). Although Eclipse has since switched to using OSGi, this code reveals identifies an opportunity for additional hoisting: if the framework itself was responsible for loading plugins, it could ensure that the Diversity Rule was maintained.
When properties or quality attributes are hoisted the application may have to follow some constraints in order to work within the architecture. For example, EJB disallows applications from starting their own threads, creating a GUI, or writing to local disk. These restrictions make sense, since it would be difficult for EJB to handle concurrency when applications created their own threads, or move applications between servers when they have data on a local disk.
Tradeoffs may be seen when hoisting. Automatic garbage collection hoists memory management but can make achieving performance targets difficult. Domain-specific concurrency patterns may be more efficient than a hoisted general-purpose mechanism.
Architecture hoisting can be seen as a kind of tyranny over developers, burdening them with additional constraints and bureaucracy, or it can be seen as liberation for developers, freeing them to focus on functionality instead of properties and quality attributes. Hoisting is just a mechanism and can be used appropriately or not. It can be most effective when the system design requires properties or quality attributes but achieving them would be a burden to developers. Often developers may be experts in the domain but not on how to ensure a quality like security or performance, so hoisting can enable experts to work within their specialty.
EDIT 20 March 2009: Thanks Bradley for pointing out the Eclipse change to OSGi which makes the plugin loading example a bit out of date.