Note that the information on this page is the BETA 1 of a guide that is now released. See
http://www.codeplex.com/AppArchGuide for the latest PDF and HTML content.
Chapter 1 - Fundamentals of Application Architecture
- J.D. Meier, Alex Homer, David Hill,
Prashant Bansode, Lonnie Wall, Rob Boucher Jr, Akshay Bogawat
- Learn the fundamentals of application architecture.
- Understand key application architecture terms and principles.
- Learn the key forces shaping today’s architectural landscape.
This chapter lays a foundation for practical application architecture. It starts by describing architecture and design at a high level and then dives deeper into specific aspects of application architecture and design. The remainder of the guide follows the
same approach. Finally, this chapter defines key terms and principles. Understanding these will help you to gain the most benefit from this guide, and be more successful as an application architect.
What Is Application Architecture?
Software architecture is often defined as the structure or structures of a system. Several well-known industry experts have expanded that definition with information on the decisions that must be made related to architecture. Here we look at a somewhat formal
definition of architecture, and then take a more informal view.
Kruchten, Booch, Bittner, and Reitman on Architecture
Philippe Kruchten, Grady Booch, Kurt Bittner, and Rich Reitman derived and refined a definition of architecture based on work by Mary Shaw and David Garlan (Shaw and Garlan 1996). Their definition is:
“Software architecture encompasses the set of significant decisions about the organization of a software system including:
- Selection of the structural elements and their interfaces by which the system is composed.
- Behavior as specified in collaboration among those elements.
- Composition of these structural and behavioral elements into larger subsystems.
- Architectural style that guides this organization.
Software architecture also involves functionality, usability, resilience, performance, reuse, comprehensibility, economic, and technology constraints, tradeoffs and aesthetic concerns.”
Fowler on Architecture
In Patterns of Enterprise Application Architecture
, Martin Fowler outlines some common recurring themes when explaining architecture:
- The highest-level breakdown of a system into its parts.
- The decisions that are hard to change.
- There are multiple architectures in a system.
- What is architecturally significant can change over a system’s lifetime.
- In the end, architecture breaks down to whatever the important stuff is.
Bass, Clements, Kazman on Architecture
In Software Architecture in Practice (2nd edition)
, Bass, Clements, and Kazman define architecture like this:
"The software architecture of a program or computing system is the structure or structures of the system, which comprise software elements, the externally visible properties of those elements, and the relationships among them. Architecture is concerned
with the public side of interfaces; private details of elements – details having to do solely with internal implementation – are not architectural."
Why Do We Need Architecture?
Like any other complex structure, software must be built on a solid foundation. Failure to consider key scenarios, design for common problems, or consider long term consequences of key decisions can put your application at risk. Modern tools and platforms help
to simplify the tasks of building applications, but they do not replace the requirement to design your application based on your scenarios. The risks exposed by poor architecture include software that is unstable, unable to support business requirements, or
could even prevent the application from working when deployed into a production environment.
Consider the following high-level concerns when thinking about software architecture:
- How will the application be deployed into production?
- How will the users be using the application?
- What are the quality attribute requirements, such as security, performance, concurrency, internationalization, and configuration?
- What are the architectural trends that may impact your application now or after it has been deployed?
Architecture vs. Design
According to Martin Fowler “the expert developers working on that project have a shared understanding of the system design. This shared understanding is called ’architecture’. This understanding includes how the system is divided into components and how the
components interact through interfaces. These components are usually composed of smaller components, but the architecture only includes the components and interfaces that are understood by all the developers.”
So architecture focuses on how components and interfaces are used by or interact with other components. Selecting data structures or algorithms implemented within the components is not architectural. Rather than use hard and fast rules to distinguish between
architecture and design, it makes sense combine these two areas. In some cases, decisions are clearly more architectural in nature. In other cases, the decisions are more about design, and how they help you realize that architecture.
User Business and System Goals
Systems should be architected with consideration for the user, the system, and the business goals. For each of these areas, outline key scenarios, important quality attributes (for example, maintainability), key satisfiers, and key dissatisfiers. When possible,
develop and consider metrics that measure success in each of these areas.
Tradeoffs are likely between each area, and a balance point must be found. For example, responsiveness may be a major user goal but the system administrator is not willing to invest in the hardware required to meet that goal for 100% of the time. A balance
point may be to meet the goal only 80% of the time.
The Goals of Architecture
Application architecture seeks to build a bridge between business requirements and technical requirements by understanding use cases, and then finding ways to implement the use cases in the software. The goal of architecture is try to identify the requirements
that impact the structure of the application. Good architecture reduces the business risks associated with building a technical solution. A good design is sufficiently flexible to be able to handle the natural drift that will occur over time in hardware and
software technology, as well as in user scenarios and requirements. An architect must consider the overall impact of design decisions, the inherent tradeoffs between quality attributes (such as performance and security), and the tradeoffs required to address
user, system, and business requirements.
Keep the following points in mind:
- Architecture should expose the structure of the system but hide the implementation details.
- Architecture should realize all of the use case scenarios.
- Architecture should try to address the concerns of various stakeholders.
- Architecture should handle both functional and quality requirements.
Approach to Architecture
There are key decisions that must be addressed with any architecture, regardless of your architectural approach. At a minimum, you must determine the type of application that you are building, the architectural styles that will be used, and how you will handle
cross cutting concerns. Throughout this guide, we use an architectural baseline for framing out the different areas that must be addressed in your architecture. The architectural baseline is shown in the following diagram.
In addition to the architectural baseline, you can use the following approach to help define your architecture. The first step is to identify type of application you plan to build. Next, you must understand how the application will be deployed. Once you know
what type of application you are building and how it will be deployed, you can start to drill down into the architecture to identify styles and technologies that you will use. Finally, you must consider how quality attributes and cross cutting concerns will
be incorporated into the design of your system.
As part of the process of designing and architecting an application, choosing the right application type is the key. The appropriate application type is governed by the requirements and infrastructure limitations. This guide covers the following application
- Mobile Applications designed for mobile devices.
- Rich Client Applications designed to run primarily on a client PC.
- Rich Internet Applications designed to be deployed from the Internet, which support rich UI and media scenarios.
- Service Applications designed to support communication between loosely coupled components.
- Web Applications designed to run primarily on the server in fully connected scenarios.
When you design your application architecture, you must take into account corporate policies and procedures; together with the infrastructure on which you plan to deploy your application. If the target environment is fixed or inflexible, your application design
must accomodate restrictions that exist in that environment. Your application design must also take into account Quality-of-Service (QoS) attributes such as security and maintainability. Sometimes you must make design tradeoffs due to protocol restrictions
and network topologies.
Identify the requirements and constraints that exist between the application architecture and infrastructure architecture early in the design process. This helps you to choose an appropriate deployment topology, and helps you resolve conflicts between the application
and infrastructure architecture early in the process.
There are many factors that influence the architectural styles that you follow. These include the capacity of your organization for design and implementation; the capabilities and experience of developers; and the infrastructure constraints and deployment scenarios
When choosing technologies for your application, the key factors to consider are the type of application you are developing, and your preferred options for application deployment topology and architectural styles. The choice of technologies will also be governed
by organization policies, infrastructure limitations, resource skills, and so on. You must compare the capabilities of the technologies you choose against your application requirements, taking into account all of these factors before making decisions
Quality attributes can be used to focus your thinking around the critical problems that your design should solve. Depending on your requirements, you may need to consider every quality attribute covered in this guide; or you may only need to consider a subset.
Every application design must consider security and performance, for example, but not every design needs to consider interoperability or scalability. Understand your requirements and deployment scenarios first so that you know which quality attributes are
important for your design. Keep in mind that quality attributes may conflict. For example, security often requires a tradeoff against performance or usability. Analyze and understand the key tradeoffs when designing for security attributes so that you are
not surprised by side effects later on.
When designing to accommodate quality attributes, consider the following guidelines:
- Quality attributes are system properties that are separate from the functionality of the system.
- From a technical perspective, implementing quality attributes can differentiate a good system from a bad one.
- There are two types of quality attributes: those that are measured at run-time, and those that can only be estimated through inspection.
- Analyze the tradeoffs between quality attributes.
Questions you should ask when considering quality attributes are:
- What are the key quality attributes required for your application? Identify them as part of the design process.
- What are the key requirements for addressing these attributes? Are they actually quantifiable?
- What are the acceptance criteria that will indicate you have met the requirements?
Cross Cutting Concerns
Cross cutting concerns represent key areas of your design that are not related to a specific layer in your application. For example, you may want to cache data in the presentation layer, the business layer, and the data access layer. You will also need to design
an exception management framework that will work within each layer and across the layers as exceptions are propagated through the system. In addition, you should design logging so that each layer can log to a common store and the results can be correlated,
and design a communication approach that you can use to communicate between the layers. Authentication and authorization concerns also exist across multiple layers, so you must determine how to pass identities and grant access to resources through the system.
The following list describes the key cross-cutting concerns that you must consider when architecting your applications:
- Authentication. Determine how to authenticate your users and pass authenticated identities across the layers.
- Authorization. Ensure proper authorization with appropriate granularity within each layer, and across trust boundaries.
- Caching. Identify what should be cached, and where to cache, to improve the performance and responsiveness of your application. Ensure that you consider Web farm and application farm issues when designing caching.
- Communication. Choose appropriate protocols, reduce calls across the network, and protect sensitive data passing over the network.
- Exception Management. Catch exceptions at the boundaries. Do not reveal sensitive information to end users.
- Instrumentation and Logging. Instrument all of the business and system critical events, and log sufficient details to recreate events in your system. Do not log sensitive information.
Agile architecture assumes that your design will evolve over time and that you cannot know everything you need to know up front in order to fully architect your system. Your design will generally need to evolve during the implementation stages of the application
as you learn more, and as you test the design against real world requirements. Create your architecture with this evolution in mind so that it agile in terms of adapting to requirements that are not fully known at the start of the design process. Consider
the following questions as you create an architectural design with agility in mind:
- What are the foundational parts of the architecture that represent the most risk if you get them wrong?
- What are the parts of the architecture that are most likely to change, or which you can delay design until later with little impact?
- What are your key assumptions, and how will you test them?
- What conditions may require you to re-factor the design?
Do not attempt to over-engineer the architecture, and do not try to know what you cannot know. Instead, keep your options open for future change, and do not paint yourself into a corner. There will be aspects of your design that you must fix early in the process,
which may represent significant cost if redesign is required. Identify these areas quickly, and invest the time necessary to get them right.
Key Principles of Agile Architecture
Agile architecture encompasses several key principles:
- Build to change over built to last. Wherever possible, design your application so that it can change over time to address new requirements and challenges.
- Model to analyze and reduce risk. Use threat models to understand risks and vulnerabilities. Use design tools and modeling systems such as UML where appropriate.
- Models and views are a communication and collaboration tool. Efficient communication of design principles and design changes is critical to an agile architecture. Use models and other visualizations to communicate your design efficiently and to enable
rapid communication of changes to the design.
- Identify key engineering decisions. Use the architecture frame in this guide to understand the key engineering decisions and the areas where mistakes are most often made. Invest in getting these key decisions right the first time so that the design
is more flexible and less likely to be broken by changes.
Incremental and Iterative Approach to Architecture
Agile architectures support an incremental and iterative approach to refinement. Do not try to get it all right the first time. Design just as much as you can in order to start testing the design against requirements and assumptions. Iteratively add detail
to the design over multiple passes to make sure you get the big decisions right first, and then focus on the details. A common failing is to dive into the details too quickly and get the big decisions wrong by making incorrect assumptions, or failing to evaluate
your architecture effectively.
Use baseline architectures to get the big picture right and use candidate architectures to iteratively test and improve your architecture. When testing an agile architecture, consider the following questions:
- What assumptions have I made in this architecture?
- What explicit or implied requirements is this architecture meeting?
- What are the key risks with this architectural approach?
- What are the counter-measures in place to mitigate key risks?
- In what ways is this architecture an improvement over the baseline or the last candidate architecture?
Baseline and Candidate Architectures
A baseline architecture describes the existing system - it is how your system looks today. If this is a new architecture, then your initial baseline is the first high-level architectural design from which candidate architectures will be built. A candidate architecture
includes the application type, the deployment architecture, the architectural style, technology choices, quality attributes, and cross cutting concerns.
An architectural spike is an end-to-end test of a small segment of the application. The purpose of an architectural spike is to reduce risk and to test potential paths. As you evolve your architecture, you may use spikes to explore different scenarios without
impacting the existing design. An architectural spike will result in a candidate architecture that can be tested against a baseline. If the candidate architecture is an improvement, it can become the new baseline from which new candidate architectures can
be created and tested. This iterative and incremental approach allows you to get the big risks out of the way first, iteratively render your architecture, and use architectural tests to prove that each new baseline is an improvement over the last.
Consider the following questions to help you test a new candidate architecture that results from an architectural spike:
- Does this architecture introduce new risks?
- Does this architecture mitigate additional known risks?
- Does this architecture meet additional requirements?
- Does this architecture enable architecturally significant use cases?
- Does this architecture address quality attribute concerns?
- Does this architecture address additional cross cutting concerns?
Architecturally Significant Use Cases
Architecturally significant use cases are use cases that meet the following criteria:
- They are important for the success and acceptance of the deployed application.
- They exercise enough of the design to be useful in evaluating the architecture.
After you have determined architecturally significant use cases for your application, you can use them as a way to evaluate the success or failure of candidate architectures. If a candidate architecture addresses more use cases, or addresses existing use cases
more effectively, it will help you to determine that this candidate architecture is an improvement over the baseline architecture.
Analyzing and Evaluating Architecture
Use architecture evaluation to determine the feasibility of your baseline and candidate architectures. Architecture evaluation is a key component of successful architecture iterations. Consider the following techniques for architecture evaluation:
- Architecturally significant use cases. Test your design against use cases that are important to the success of your application, and which exercise a significant portion of the design.
- Scenario-based evaluations. Use scenarios to analyze your design with a focus on quality attributes. Examples of scenario-based evaluations are: Architecture Trade-off Analysis Method (ATAM), Software Architecture Analysis Method (SAAM), and Active
Reviews for Intermediate Designs (ARID).
Representing and Communicating the Architecture
Communicating your design is critical for architecture reviews, as well as for the use of your architecture during implementation. In the end, your architecture is only as good as the quality of communication of your ideas. You must communicate your architectural
design to a variety of roles, including system designers, developers, system administrators, and management.
One way to think of an architectural view is as a map of the important decisions. The map is not the terrain. Instead, it is an abstraction that helps you to share and communicate the architecture.
The Architectural Landscape
Understand the key forces at work that are shaping architectural decisions today, and which will change how architectural decisions are made in the future. These key forces are driven by user demand; as well as by business demand for faster results, better
support for varying work styles and workflows, and improved adaptability of software design.
Consider the following key trends:
- User Empowerment. A design that supports user empowerment is flexible, configurable and focused on the user experience. Design your application with user personalization and options in mind. Allow the user to define how they interact with your application
instead of dictating to them. Understand the key scenarios and make them as simple as possible; make it easy to find information and use the application.
- Market Maturity. Take advantage of market maturity by leveraging existing platform and technology options. Build on higher-level application frameworks where it makes sense so that you can focus on what is uniquely valuable in your application, rather
than building what already exists and can be reused. Leverage patterns that provide rich sources of proven solutions for common problems.
- Agility and Adaptability. An agile, adaptable design takes advantage of loose coupling to allow reuse. Take advantage of pluggable designs to provide extensibility. Take advantage of service-orientation techniques such as SOA to provide interoperability.
- Future Trends. When building your architecture, understand the future trends that may impact your design after deployment. For example, consider trends in rich UI and media, composition models such as mashups, increasing network bandwidth and availability,
increasing use of mobile devices, continued improvement of hardware performance, interest in community and personal publishing models, the rise of cloud-based computing, and remote operation.
Examples and Definitions
The following sections briefly describe some of the types of applications, infrastructures, and development approaches in common use today.
- Business Process Management (BPM). A process for orchestrating interactions between the people, applications, technologies, and the related process activities in order to create value for the customer and the organization.
- Composite / Mash Ups. Techniques for combining services, applications, and resources to create interfaces that can provide more comprehensive and useful tools. Composition can occur on the server-side or on the client.
- Dynamic Languages. High-level programming languages that execute at runtime many common behaviors that a non-dynamic language might perform during compilation, such as extending objects and definitions or modifying the type system.
- Functional Programming. A technique that emphasizes the application of functions instead of focusing on state changes. It can describe just the operations performed on the program inputs without using temporary variables to store intermediate results.
- Health. A measure of the way that the system is behaving compared to expected or usual operation, taking into account load and environment factors. Health is usually monitored through an environment or tool that checks the state of a range of aspects
defined within the application, which are driven by events and performance counters that react to operational changes.
- Model-Driven Architecture (MDA). A technique for specifying, in a platform-independent way, the functionality and behavior of a distributed application without concern for the implementation technology. A complete MDA specification consists of a
definitive platform-independent base UML model and one or more platform-specific models and interface definition sets that describe how the base model is implemented.
- Representational State Transfer (REST). A technique to achieve resource-oriented stateless and/or synchronous user interaction using the standard GET, POST, PUT and DELETE commands. Often used on the Web to achieve an open publishing medium where
the URI directly describes the target and the operation.
- Software plus Services / Software as a Service (S+S / SaaS). An approach to application development that combines hosted services accessed over the Internet (in what is usually termed "the cloud") with locally executed software. These services
are consumed by software that is more directly suited to running locally on the user's machine, which may be a PC or any other Internet-enabled device, to provide a rich, seamlessly integrated user experience and a more comprehensive solution than traditional
- Platform as a Service (PaaS). An approach to application development that allows organizations to locate their applications at remote hosting companies (in what is usually termed "the cloud"), and access the functionality over the Internet.
- Service Oriented Architecture (SOA). A design that uses services with discoverable interfaces, with which consumers can interact by exchanging well-defined messages, irrespective of platform or implementation technology differences. SOA provides
a decoupled design that makes it easy to combine and reuse services.
- Rich Internet Application (RIA). A Web-based application that runs in the browser in a sandbox, and provides a richer user experience, better responsiveness, and improved network efficiency compared to traditional Web applications. It specifically
aims to support intense animation capabilities, rich media streaming, and highly graphical interfaces without requiring post-backs to the server.
- Testability. A characteristic of software that indicates how easy it is to perform testing and verification that the code is correct and performs as designed and expected. Good testability reduces the cost and effort of testing and maintaining an
application, and may be performed using an automated test environments and metrics that help to locate parts of a program which contribute to a lack of testability.
- User Empowerment. The extent to which an application gives users control of different aspects or features, including elements of discovery and satisfaction. Effectively it describes a shift in power from the business and technology to the user.
- User Experience. The overall impression for the user that the system works quickly, reliably, and does what they expect so that using it is a pleasure. User experience includes a wide range of factors from appearance and intuitiveness, to interactivity
and ease of use.
- Cloud Computing. A range of ways that consumer applications can access remote services to create a rich, seamlessly integrated user experience and a more comprehensive solution than traditional multi-tiered applications. Connected with Software plus
Services (S+S), Software as a Service (SaaS), and Platform as a Service (PaaS), where applications can be installed "in the cloud" and accessed by consumers that combine these services into a feature-rich UI.
- Green IT. The increasingly important techniques for minimizing the impact of computer systems and data centers in terms of power usage, recyclability of materials, and environmental factors. These factors contribute to reducing business operations
cost, as well as fulfilling the perceived need to "save the planet".
- Virtualization. A technique for running separate or multiple versions of the operating system on one or more servers with the aim of reducing the total number of servers required, and therefore reducing cost and environmental impact. Virtualization
also helps to maximize server efficiency, and simplify deployment and maintenance.
- Very Large Databases (VLDB). An environment or storage space consisting of vast quantities of information that is managed by a relational database management system (RDBMS), and incorporates the concepts of the physical hardware and software plus
the virtual information content. Also connected with Very Large Data Warehouses (VLDW), which are structures or architectures that serve a specific business purpose.
- Performance. The measurable capabilities of a system, which can encompass a range of factors related to execution speed, the capacity to handle information, and the overall results that the system can produce.
- Grid Computing. A distributed computing approach that combines networked, loosely-coupled and (usually) geographically separated computers that act together to perform very large tasks. This approach is often applied to computationally-intensive
scientific, mathematical, and academic problems; sometimes through volunteers who run parts of the program when their own computer is idle.
- High Performance Computing (HPC). Describes a single installation of a super-computer that can perform very large processing tasks quickly. HPC also encompasses the design of software for the clustered systems that make up a super-computer. This
approach is often applied to computationally-intensive scientific, mathematical, and academic problems; for example, weather forecasting and complex real-time analysis scenarios.
- Many-core / Multi-core. Techniques for improving the processing power of computers using CPU chips that contain multiple individual processing cores. The cores can operate in parallel and handle different threads of a program to provide better performance.
The most powerful servers may contain several multi-core processors.
- Parallel Computing. Techniques for executing a program on more than one processor or processor core concurrently by dividing the work into small chunks on which each processor can operate independently. The software manages the allocation of tasks
to each processor and then combines the results.
- Application Life-Cycle Management (ALM). An approach to managing the complete lifetime of applications and systems that encompasses all of the stages; including requirements analysis, design and modeling, development and testing, deployment, and
runtime monitoring and maintenance. It reflects the realization that the major proportion of the Total Cost of Ownership (TCO) for applications occurs after development is complete, during the runtime and maintenance cycles of the lifetime of the application.
- Distributed Teams. Increasingly, through the use of new communications technologies and broadband global networks, teams of developers and other software or applications-related staff can operate efficiently from different geographical locations.
This allows a wider choice of team members that can maximize the overall capabilities of the team, while reducing costs.
- Agile. A project management process based on short and time-boxed iterations of work defined through frequent inspection and adaptation of goals and achievements. It usually involves a small, cross-functional, and self-organizing team whose members
interact through pairing and face-to-face communication rather than through written documentation. It encourages team work, self-organization, accountability, and use of software best practices to provide rapid delivery of high-quality software that meets
both customer needs and company goals.
- Lean. An extension of agile development principles that focuses on seven specific areas. These areas include eliminating waste, amplifying learning, empowering the team, deciding late but delivering early, and seeing the whole rather than the parts.
- User-Led. A term that is usually applied to scenarios where the user has direct influence over the design and features of a system or product through involvement early in the project. It also describes how users increasingly expect systems to be
adaptable and configurable to suit their requirements – factors that must be incorporated at design time. Other uses of the term include the increasing proliferation of social sites and mechanisms that allow users to create content, influence, and participate.