Chapter #9 Architecture in Pratice— Software Design and Architecture Specialization University of Alberta
Software architecture plays a crucial role in defining how a software system’s elements interact with each other and determining the quality of the system. While design patterns and principles address specific technical issues, software architecture goes beyond that, taking into account both functional and non-functional requirements. It provides a holistic view of the system, setting guidelines for the use of design patterns and principles to ensure conceptual integrity and consistency.
Software architecture aims to address a wide range of issues, including non-functional qualities like testability, usability, and availability, in addition to functional aspects. It evaluates how well the software elements work together to provide functionality, handle potential system issues, and improve the user experience and development ease.
There is no universal definition of “good” or “bad” software architecture. Instead, architecture is designed to meet specific requirements and solve particular problems. Different architectures are suitable for different contexts, and what may be a good architecture for one context could be inappropriate for another.
Modern systems often require a combination of architectural designs because their requirements are complex and may not align with a single architecture. Non-functional requirements can vary among different stakeholders, making it important to prioritize system requirements and find a balance between different qualities.
Quality attributes are used to determine the quality of a system’s design, runtime performance, and usability. Measurable quality attributes provide an objective means of evaluating a system’s performance, such as system availability measured by uptime.
Industry consensus identifies various quality attributes that can be used to evaluate a system, including maintainability, reusability, flexibility, and other developer-centric attributes. These attributes help guide the design and evaluation of software architecture, ensuring that it meets the needs of all stakeholders. Context plays a significant role in determining which quality attributes are most relevant for a specific system architecture.
Quality attributes play a vital role in evaluating software architecture. Here are some key attributes and their measurements:
- Maintainability: This measures how easily a system can undergo changes throughout its lifecycle. High maintainability ensures that the system can accommodate changes efficiently and effectively.
- Reusability: This attribute measures the extent to which functions or parts of a system can be reused in another context. High reusability reduces the cost of re-implementing functionalities that have already been developed.
- Flexibility: This indicates how well a system can adapt to changes in requirements. A highly flexible system can adapt to future changes efficiently and at a reasonable cost.
- Modifiability: This measures a system’s ability to handle changes, incorporate new functionalities, or remove existing ones. It is essential to balance the cost of implementing changes with this attribute, as it can be expensive to achieve.
- Testability: This attribute assesses how easy it is to identify errors through executable tests. A highly testable system allows for quick and easy testing without the need for a user interface. This facilitates the identification and resolution of faults before system release.
- Conceptual Integrity: This refers to the consistency maintained across the entire system, including adherence to naming and coding conventions. Conceptual integrity ensures a cohesive and coherent system architecture.
Considering these quality attributes during the design and evaluation of software architecture can contribute to the development of robust, adaptable, and maintainable systems that meet the needs of the stakeholders.
When considering software architecture, it’s crucial to evaluate the quality attributes from the user’s perspective. Here are some key attributes and their measurements:
- Availability: This measures the amount of time a system remains operational over a specific period. System availability is determined by uptime and reflects how well the system recovers from errors, high loads, or updates. A reliable system should prevent these issues from causing significant downtime.
- Interoperability: This assesses the system’s ability to communicate and share data with external systems. It involves understanding interfaces and exchanging information under specific conditions with external systems. Modern systems are designed to be interoperable and capable of exchanging information using various communication protocols and data formats.
- Security: This attribute evaluates the system’s capability to safeguard sensitive data from unauthorized and unauthenticated use. It is essential for systems to protect sensitive information from unauthorized access while ensuring authorized users have the necessary access. Data integrity is closely associated with security, as the system must control who can access and modify the data.
- Performance: This measures the system’s throughput and latency in response to user commands and events. Throughput indicates the volume of output produced over time, while latency indicates the time taken to produce an output after receiving an input. Performance significantly influences architecture and is critical for ensuring a smooth user experience.
- Cost-Efficiency: This considers the system’s price relative to its performance. Lowering the price per unit of performance is a key goal, especially with advancing technology. Striving for cost-efficiency ensures that the system delivers high performance without excessive costs.
- Usability: This attribute gauges how easily users can learn and use the system’s functions. High usability implies that the system effectively addresses end users’ needs by being intuitive, minimizing user errors, providing feedback, and facilitating task completion.
Considering these user-centric quality attributes is vital for developing software architecture that not only meets the technical requirements but also fulfills the expectations and needs of the system’s users.
Designing an appropriate system architecture is critical for ensuring the success and maintainability of software systems. Here are some key considerations and guidelines to keep in mind during the design process:
1. Prioritize Quality Attributes: Recognize the importance of quality attributes and prioritize them according to the specific needs of each system. Maintain an updated record of how the system meets these attributes, including any trade-offs made during the design process.
2. Involve Technical Leads: Engage technical leads in the design process to identify potential challenges and ensure that the architectural design aligns with the capabilities of the chosen technologies. Their insights can help foresee and address potential implementation difficulties.
3. Consider Stakeholder Perspectives: Adopt a design approach that takes into account the perspectives of different stakeholder groups. Ensuring conceptual integrity throughout the system involves defining well-designed subsystems, maintaining consistent implementation of functions, and establishing rules for resource utilization.
4. Document the Architecture: Maintain detailed and up-to-date documentation of the system architecture. This documentation serves as a shared resource to record the architectural vision, facilitating cohesion and continuity in design, especially if team members change over time.
5. Reduce Complexity: Strive to minimize unnecessary complexity in the system design. Complexity can lead to increased development time and costs, and a simpler architecture that meets all system requirements efficiently is often preferable.
By following these guidelines and principles, you can create a well-designed system architecture that meets the requirements and expectations of all stakeholders involved. It is essential to consider both the perspectives of the developers and the end users, focusing on attributes such as maintainability, reusability, flexibility, testability, and conceptual integrity, as well as aspects like availability, security, performance, and usability.
Analyzing and Evaluating an Architecture
Analyzing and evaluating a software architecture is essential to ensure that it effectively meets the requirements and concerns of all stakeholders. To achieve this, a systematic approach is necessary, considering various behaviors, quality attributes, and specific characteristics of the system. One method of evaluating quality attributes involves using quality attribute scenarios to determine whether a system can fulfill the established requirements for a particular attribute.
There are two main types of scenarios: general scenarios, which provide a characterization for any system, and concrete scenarios, which specifically characterize a particular system. Both types of scenarios contain several key components, including a stimulus source, a stimulus, an environment, an artifact, a response, and a response measure. These components help define the conditions under which the system is expected to perform and how it should respond to specific stimuli. Additionally, response measures are used to quantitatively assess the system’s response to stimuli, allowing for a more objective evaluation based on metrics such as response time, failure probability, repair time, and average system load.
When analyzing and evaluating software architecture, it is important to focus on scenarios that deviate from the normal execution path, as these are the situations that can significantly impact the system’s quality attributes. Scenarios involving incorrect inputs, heavy system loads, or potential security breaches should be given high priority in the evaluation process. By addressing and preparing for such scenarios, a system can better handle unexpected failures, thereby enhancing its overall performance and reliability.
For instance, when evaluating the availability of a system, it is crucial to consider not only its normal operational state but also potential scenarios where the system might become unavailable. This comprehensive assessment ensures that the system remains robust and capable of maintaining its availability even in challenging conditions. By employing quality attribute scenarios and considering a range of potential situations, software architects can effectively evaluate the architecture’s performance and suitability for meeting the intended objectives.
Architecture Trade-off Analysis Method
The Architecture Trade-off Analysis Method (ATAM) is a well-established evaluation technique developed by the Software Engineering Institution at Carnegie Mellon University. One of the key advantages of ATAM is that it allows for the evaluation of a system by external parties who may not be familiar with the architecture or the problem space. This methodology involves three distinct groups of participants, each contributing to a comprehensive evaluation process.
The first group is the evaluation team, which is divided into three subgroups: designers, peers, and outsiders. Designers are actively involved in the architectural design process, employing iterative and hypothesis-driven methods to analyze requirements and create a design that effectively addresses those requirements. Peers, on the other hand, are individuals associated with the project but not directly involved in the design phase. Their insights help provide a well-rounded perspective on design decisions. Finally, outsiders, who are external to the project or organization, contribute their experience and expertise to the evaluation, thereby reducing potential bias toward the project.
Project decision makers constitute another key group of participants, encompassing representatives with the authority to make project-related decisions. This group typically includes project managers, clients, product owners, software architects, and technical leads. The third group, architecture stakeholders, comprises individuals who have a vested interest in ensuring that the architecture effectively addresses the business needs, even if they are not directly involved in the evaluation process. This group may consist of end users, developers, and support staff, among others.
The initiation of a software project under the ATAM framework begins with the identification of business drivers, which highlight the specific need for a system to address particular problems. These business drivers, in conjunction with the system architecture, determine the system’s quality attributes, the architectural approach taken, and the design decisions made. Together, these elements contribute to the formulation of quality attribute scenarios, which form the basis of the ATAM evaluation process. By employing this structured methodology, organizations can thoroughly assess the viability and effectiveness of their software architecture, enabling them to make informed decisions and improvements as needed.
Relationship to Organizational Structure
The relationship between organizational structure and software architecture has been a subject of interest in the field of software development. A study conducted by the Harvard Business School revealed that looser organizational structures, such as those found in open-source projects, tend to produce more loosely coupled modular code, while in-house development teams often produce more tightly coupled code. This difference in coupling may arise from conscious decisions made by developers or may simply be a natural consequence of the specific development environment.
This study aligns with Conway’s Law, which suggests that a software system is likely to reflect the organizational structure of the team that created it. Understanding Conway’s Law is crucial when assembling a software development team. Rather than forming a team solely focused on a project with constant communication, which can result in a tightly coupled system, it is advisable to consider the desired architecture when planning the development teams. Many programmers are aware of Conway’s Law, either explicitly or intuitively, and thus it is prudent to organize the team around the intended software architecture.
For instance, in the context of building a web application using the n-Tier architecture, one might consider having separate teams for the data backend, the application logic layer, and the presentation tier. This approach underscores the importance of flexibility in design, especially when the implementation of a component is not yet known or is subject to change.
Conway’s Law implies that additional effort may be necessary to establish unified and scalable architectures. It might be necessary to create a specialized team tasked with consolidating and enforcing common services across the entire system. By recognizing and considering the implications of Conway’s Law, software development teams can better align their organizational structure with their desired software architecture, ultimately leading to more effective and cohesive system development.
Product Lines and Product Families
Developers must consistently seek opportunities for code re-use throughout their work. The software industry has effectively utilized code re-use through the use of libraries, toolkits, and engines. Leveraging code re-use, even with modifications, saves time and resources, and provides access to proven, robust solutions. Therefore, well-written and well-documented code is crucial for successful code re-use.
One effective way to capitalize on code re-use is by treating a group of products as a product line. Product lines, or product families, consist of products that often share the same operating system, enabling extensive code re-use. For instance, iOS is a well-known example of a product line utilized across various Apple products such as iPhones, iPads, and iPod Touch devices. Product lines offer several advantages:
- Reduced development costs: Similar features in product lines help companies save money by decreasing their development costs per product. The time saved on development can be redirected toward testing for quality attributes such as reliability, user experience, security, and maintainability. Additionally, since reused code has already been tested, less testing is required overall for each product.
- Enhanced user experience: Common characteristics among products in a product line contribute to a shorter learning curve for both customers and developers. This may also drive the sales of other products within the same product line.
- Faster time to market: Since most software components are already developed, creating a new product within the product line or refining an existing one takes less time.
While treating a single or small number of products as a product line may not be cost-effective, it could still be beneficial if there are plans to develop more products in the future. Implementing a product line requires upfront work to establish the foundations for the products.
The book “Software Product Lines in Action” (2007) provides valuable insights into architectural considerations for software product lines. Some of the key steps outlined in this resource include:
- Identifying commonalities: Determine the features that remain consistent in every product.
- Identifying variations: Recognize the features within the product line that vary between products. For example, in a line of tablets, a variation could involve support for different cellular network connections.
- Determining product specifics: Identify the features that are unique to a single product, which will be developed by the team responsible for that product. For instance, a tablet designed for reading eBooks might include additional tools for managing eBooks and support for an eInk section.
Ibrahim Can Erdoğan