33.7. The Art: Resolution of Architectural Factors
One could say the science of architecture is the collection and organization of information about the architectural factors, as in the factor table. The art of architecture is making skillful choices to resolve these factors, in light of trade-offs, interdependencies, and priorities.Adept architects have knowledge in a variety of areas (for example, architectural styles and patterns, technologies, products, pitfalls, and trends) and apply this to their decisions.
Recording Architectural Alternatives, Decisions, and Motivation
Ignoring for now principles of architectural decision-making, virtually all architectural methods recommend keeping a record of alternative solutions, decisions, influential factors, and motivations for the noteworthy issues and decisions.Such records have been called technical memos [Cunningham96], issue cards [HNS00], and architectural approach documents (SEI architectural proposals), with varying degrees of formality and sophistication. In some methods, these memos are the basis for yet another step of review and refinement.In the UP, the memos should be recorded in the SAD.An important aspect of the technical memo is the motivation or rationale. When a future developer or architect needs to modify the system,[3] it is immensely helpful to understand the motivations behind the design, such as why a particular approach to recovery from remote service failure in the NextGen POS was chosen and others rejected, in order to make informed decisions about changing the system.
[3] Or when four weeks have passed and the original architect has forgotten their own rationale!
Explaining the rationale of rejecting the alternatives is important, as during future product evolution, an architect may reconsider these alternatives, or at least want to know what alternatives were considered, and why one was chosen.A sample technical memo follows that records an architectural decision for the NextGen POS. The exact format is, of course, not important. Keep it simple and just record information that will help the future reader make an informed decision when changing the system.
Technical Memo: Issue: ReliabilityRecovery from Remote Service FailureSolution Summary: Location transparency using service lookup, failover from remote to local, and local service partial replication. Factors
Solution Achieve protected variation with respect to location of services using an Adapter created in a ServicesFactory. Where possible, offer local implementations of remote services, usually with simplified or constrained behavior. For example, the local tax calculator will use constant tax rates. The local product information database will be a small cache of the most common products. Inventory updates will be stored and forwarded at reconnection.See also the AdaptabilityThird-Party Services technical memo for the adaptability aspects of this solutions, because remote service implementations will vary at each installation.To satisfy the quality scenarios of reconnection with the remote services ASAP, use smart Proxy objects for the services, that on each service call test for remote service reactivation, and redirect to them when possible.Motivation Retailers really don't want to stop making sales! Therefore, if the NextGen POS offers this level of reliability and recovery, it will be a very attractive product, as none of our competitors provide this capability. The small product cache is motivated by very limited client-side resources. The real third-party tax calculator is not replicated on the client primarily because of the higher licensing costs, and configuration efforts (as each calculator installation requires almost weekly adjustments). This design also supports the evolution point of future customers willing and able to permanently replicate services such as the tax calculator to each client terminal.Unresolved Issues noneAlternatives Considered A "gold level" quality of service agreement with remote credit authorization services to improve reliability. It was available, but much too expensive. |
Priorities
There is a hierarchy of goals that guides architectural decisions:
- Inflexible constraints, including safety and legal compliance.
- The NextGen POS must correctly apply tax policies.
- Business goals.
- Demo of noteworthy features ready for the POSWorld trade show in Hamburg in 18 months.
- Has qualities and features attractive to department stores in Europe (for example, multi-currency support and customizable business rules).
- All other goals
- These can often be traced back to directly stated business goals, but are indirect. For example, "easily extendible: can add <some unit of functionality> in 10 person weeks" could trace to a business goal of "new release every six months."
Technical Memo: Issue: LegalTax Rule ComplianceSolution Summary: Purchase a tax calculator component. Factors
Solution Purchase a tax calculator with a licensing agreement to receive ongoing tax rule updates. Note that different calculators may be used at different installations.Motivation Time-to-market, correctness, low maintenance requirements, and happy developers (see alternatives). These products are costly, which affects our cost-containment and product pricing business goals, but the alternative is considered unacceptable.Unresolved Issues What are the leading products and their qualities?Alternatives Considered Build one by the NextGen team? It is estimated to take too long, be error prone, and create an ongoing costly and uninteresting (to the company's developers) maintenance responsibility, which affects the goal of "happy developers" (surely, the most important goal of all). |
Priorities and Evolution Points: Under- and Over-engineering
Another distinguishing feature of architectural decision-making is prioritization by probability of evolution points points of variability or change that may arise in the future. For example, in NextGen, there is a chance that wireless handheld client terminals will become desirable. Designing for this has a significant impact because of differences in operating systems, user interface, hardware resources, and so forth.The company could spend a huge amount of money (and increase a variety of risks) to achieve this "future proofing." If it turns out in the future that this was not relevant, doing it would be a very expensive exercise in over-engineering. Note also that future proofing is arguably rarely perfect, since it is speculation; even if the predicted change occurs, some change in the speculated design is likely.On the other hand, future proofing against the Y2K date problem would have been money very well spent; instead, there was under-engineering with a wickedly expensive result.
The art of the architect is knowing what battles are worth fightingwhere it's worth investing in designs that provide protection against evolutionary change. |
Basic Architectural Design Principles
The core design principles explored in much of this book that were applicable to small-scale object design are still dominant principles at the large-scale architectural level:
- low coupling
- high cohesion
- protected variation (interfaces, indirection, service lookup, and so forth)
However, the granularity of the components is largerit is low coupling between applications, subsystems, or process rather than between small objects.Furthermore, at this larger scale, there are more or different mechanisms to achieve qualities such as low coupling and protected variation. For example, consider this technical memo:
Technical Memo: Issue: AdaptabilityThird-Party ServicesSolution Summary: Protected Variation using interfaces and Adapters Factors
Solution Achieve protected variation as follows: Analyze several commercial tax calculator products (and so forth for the other product categories) and construct common interfaces for the lowest common denominators of functionality. Then use Indirection via the Adapter pattern. That is, create a resource Adapter object that implements the interface and acts as connection and translator to a particular back-end tax calculator. See also the ReliabilityRecovery from Remote Service Failure technical memo for the location transparency aspects of this solution.Motivation Simple. Cheaper, and faster communication than using a messaging service (see alternatives), and in any event a messaging service can't be used to directly connect to the external credit authorization service.Unresolved Issues Will the lowest common denominator interfaces create an unforeseen problem, such as too limited?Alternatives Considered Apply indirection by using a messaging or publish-subscribe service (e.g., a JMS implementation) between the client and tax calculator, with adapters. But not directly usable with a credit authorizer, costly (for reliable ones), and more reliability in message delivery than is practically needed. |
Separation of Concerns and Localization of Impact
Another basic principle applied during architectural analysis is to achieve a separation of concerns . It is also applicable at the scale of small objects, but achieves prominence during architectural analysis.Cross-cutting concerns are those with a wide application or influence in the system, such as data persistence or security. One could design persistence support in the NextGen application such that each object (that contained application logic code) itself also communicated with a database to save its data. This would weave the concern of persistence in with the concern of application logic, in the source code of the classesso too with security. Cohesion drops and coupling rises.In contrast, designing for a separation of concerns factors out persistence support and security support into separate "things" (there are very different mechanisms for this separation). An object with application logic just has application logic, not persistence or security logic. Similarly, a persistence subsystem focuses on the concern of persistence, not security. A security subsystem doesn't do persistence.Separation of concerns is a large-scale way of thinking about low coupling and high cohesion at an architectural level. It also applies to small-scale objects, because its absence results in incohesive objects that have multiple areas of responsibility. But it is especially an architectural issue because the concerns are broad, and the solutions involve major, fundamental design choices.There are several large-scale techniques to achieve a separation of concerns:
- Modularize the concern into a separate component (for example, subsystem) and invoke its services.
- This is the most common approach. For example, in the NextGen system, the persistence support could be factored into a subsystem called the persistence service . Via a facade, it can offer a public interface of services to other components. Layered architectures also illustrate this separation of concerns.
- Use decorators.
- This is the second most common approach; first popularized in the Microsoft Transaction Service, and afterwards with EJB servers. In this approach, the concern (such as security) is decorated onto other objects with a Decorator object that wraps the inner object and interposes the service. The Decorator is called a container in EJB terminology. For example, in the NextGen POS system, security control to remote services such as the HR system can be achieved with an EJB container that adds security checks in the outer Decorator, around the application logic of the inner object.
- Use post-compilers and aspect-oriented technologies.
- For example, with EJB entity beans one can add persistence support to classes such as Sale . One specifies in a property descriptor file the persistence characteristics of the Sale class. Then, a post-compiler (by which I mean another compiler that executes after the "regular" compiler) will add the necessary persistence support in a modified Sale class (modifying just the bytecode) or subclass. The developer continues to see the original class as a "clean" application-logic-only class. Another variation is aspect-oriented technologies such as AspectJ (www.aspectj.org), which similarly support post-compilation weaving in of cross-cutting concerns into the code, in a manner that is transparent to the developer. These approaches maintain the illusion of separation during development work, and weave in the concern before execution.
Promotion of Architectural Patterns
An exploration of architectural patterns and how they could apply (or misapply) to the NextGen case study is out of scope in this introductory text. However, a few pointers:Probably the most common mechanism to achieve low coupling, protected variation, and a separation of concerns at the architectural level is the Layers pattern, which has been introduced a previous chapter. This is an example of the most common separation techniquemodularizing concerns into separate components or layers.There is a large and growing body of written architectural patterns. Studying these is the fastest way I know of to learn architectural solutions. Please see the recommended readings.