Software Engineering Chapter 4 - Software Architecture
Issues that Influence Architectural Decisions
- Non-functional product characteristics - Product Lifetime - Software Reuse - Number of users - Software Compatibility
To create a reliable, secure and efficient product, you need to pay attention to architectural design which includes
- Overall organization - How the software is decomposed into components - The server organization - The technologies that you use to build the software
Number of Users
If you are developing consumer software delivered over the Internet, the number of users can change very quickly. - This can lead to serious performance degradation unless you design your architecture so that your system can be quickly scaled up and down.
Cross-cutting concerns
Cross-cutting concerns are concerns that are systemic, that is, they affect the whole system. - In a layered architecture, cross-cutting concerns affect all layers in the system as well as the way in which people use the system. - Every layer has to take them into account and there are inevitably interactions between the layers because of these concerns. - The existence of cross-cutting concerns is the reason why modifying a system to improve its security after it has been designed is often difficult.
Product Lifetime
If you anticipate a long product lifetime, you need to create regular product revisions - You therefore need an architecture that can evolve, so that it can be adapted to accommodate new features and technology.
Component organization
- Abstraction in software design means that you focus on the essential elements of a system or software component without concern for its details. - At the architectural level, your concern should be on large-scale architectural components - Decomposition involves analyzing these large-scale components and representing them as a set of finer-grain components. - Layered models are often used to illustrate how a system is composed of components.
Layer functionality in a web-based application
- Browser-based or mobile user interface - Authentication and UI management - Application-specific functionality - Basic shared services - Database and transaction management
Architectural Complexity
- Complexity in a system architecture arises because of the number and the nature of the relationships between components in that system. - It is always preferable to use local data wherever possible and to avoid sharing data if you can. - When decomposing a system into components, you should try to avoid unnecessary software complexity. 1. Localize relationships: If there are relationships between components A and B, these are easier to understand if A and B are defined in the same module. 2. Reduce shared dependencies: Where components A and B depend on some other component or data, complexity increases because changes to the shared component mean you have to understand how these changes affect both A and B.
Design guidelines and layered architectures
- Each layer is an area of concern and is considered separately from other layers. - The top layer is concerned with user interaction, the next layer down with user interface management, the third layer with information retrieval and so on. - Within each layer, the components are independent and do not overlap in functionality. - The lower layers include components that provide general functionality so there is no need to replicate this in the components in a higher level. - The architectural model is a high-level model that does not include implementation information. - Ideally, components at level X (say) should only interact with the APIs of the components in level X-1. That is, interactions should be between layers and not across layers. - This is often impossible without code duplication. The lower levels of the stack of layers provide basic services that may be required by components that are not in the immediate level above them. - In a layered model, components in lower layers should never depend on higher-level components. - Dependencies should be on lower-level components. - That is, if you change a component at level X in the stack, you should not have to make changes to components at lower levels in the stack. You only have to consider the effects of the change on components at higher levels.
Centralized Security Architectures
- Easier to design and build protection and that the protected information can be accessed more efficiently - However, if your security is breached, you lose everything. - If you distribute information, it takes longer to access all of the information and costs more to protect it, plus only lose the information that you have stored in that location if there is a breach.
Why is architecture important?
- The architecture of a system has a fundamental influence on the non-functional system properties - Non-functional attributes, rather than product features, influence user judgements about the quality of your software. - Architectural design involves understanding the issues that affect the architecture of your product and creating an architectural description that shows the critical components and their relationships. - Minimizing complexity should be an important goal for architectural designers, the more complex a system, the more difficult and expensive it is to understand and change, programmers are more likely to make mistakes and introduce bugs and security vulnerabilities when they are modifying or extending a complex system.
Distribution architecture
- The distribution architecture of a software system defines the servers in the system and the allocation of components to these servers. - Client-server architecture is a type of distribution architecture that is suited to applications where clients access a shared database and business logic operations on that data. -
Architectural Design Guidelines
1. Separation of concerns - Organize your architecture into components that focus on a single concern. 2. Stable Interfaces - Design component interfaces that are coherent and that change slowly. 3. Implement Once - Avoid duplicating functionality at different places in your architecture.
Database and transaction management
A database layer that provides services such as transaction management and recovery. If your application does not use a database, then this may not be required.
Usability Issues with Security
A layered approach to security affects the usability of the software. - Users have to remember information, like passwords, that is needed to penetrate a security layer. Their interaction with the system is inevitably slowed down by its security features. - Many users find this irritating and often look for workarounds so that they do not have tore-authenticate to access system features or data. To avoid this, you need an architecture: - that doesn't have too many security layers - that doesn't enforce unnecessary security - that provides helper components that reduce the load on users
Basic Shared Services
A shared services layer that includes components that provide services used by the application layer components.
Authentication and UI management
A user interface management layer that may include components for user authentication and web page generation.
Browser-based or mobile user interface
A web browser system interface in which HTML forms are often used to collect user input. Javascript components for local actions, such as input validation, should also be included at this level. Alternatively, a mobile interface may be implemented as an app.
Non-functional product characteristics
Affect all users - If you get these wrong, your product is unlikely to be a commercial success. - Unfortunately, some characteristics are opposing, so you can optimize only the most important. - Ex: Security, Performance
Application-specific functionality
An "application" layer that provides functionality of the application. Sometimes this may be expanded into more than one layer.
Component
An element that implements a coherent set of functionality or features. - Can be considered as a collection of one or more services that may be used by other components. - When designing software architecture, you don't have to decide how an architectural element or component is to be implemented, rather you design the component interface and leave the implementation of that interface to a later stage of the development process.
Security as a cross-cutting concern
Different technologies are used in different layers such as an SQL database or a Firefox browser. Attackers can try to use vulnerabilities in these technologies to gain access. Consequently, you need protection from attacks at each layer as well as protection at lower layers in the system from successful attacks that have occurred at higher-level layers. If there is only a single security component in a system, this represents a critical system vulnerability. If all security checking goes through that component and it stops working properly or is compromised in an attack, then you have no reliable security in your system. By distributing security across the layers, your system is more resilient to attacks and software failure (remember the Rogue One example earlier in the chapter).
Maintainability and Performance
Figure 4.2(Shared Database Architecture slide) shows a system with two components (C1 and C2) that share a common database. - Assume C1 runs slowly because it has to reorganize the information in the database before using it. - The only way to make C1 faster might be to change the database. This means that C2 also has to be changed, which may, potentially, affect its response time. In Figure 4.3(Multiple Database Architecture slide), a different architecture is used, where each component has its own copy of the parts of the database that it needs. - If one component needs to change the database organization, this does not affect the other component. - However, a multi-database architecture may run more slowly and may cost more to implement and change. - A multi-database architecture needs a mechanism(component C3) to ensure that the data shared by C1and C2 is kept consistent when it is changed.
Software Compatibility
For some products, it is important to maintain compatibility with other software so that users can adopt your product and use data prepared using a different system. - This may limit architectural choices, such as the database software that you can use.
Architectural design questions
How should the system be organized as a set of architectural components, where each of these components provides a subset of the overall system functionality? - The organization should deliver the system security, reliability and performance that you need. How should these architectural components be distributed and communicate with each other? What technologies should you use in building the system and what components should be reused?
The influence of architecture on system security - A centralized security architecture
In the Star Wars prequel Rogue One (https://en.wikipedia.org/wiki/Rogue_One),the evil Empire has stored the plans for all of their equipment in a single, highly secure, well guarded, remote location. This is called a centralized security architecture. It is based on the principle that if you maintain all of your information in one place, then you can apply lots of resources to protect that information and ensure that intruders can't get it. Unfortunately (for the Empire), the rebels managed to breach their security. They stole the plans for the Death Star, an event that underpins the whole Star Wars saga. In trying to stop them, the Empire destroyed their entire archive of system documentation with who knows what resultant costs. Had the Empire chosen a distributed security architecture, with different parts of the Death Star plans stored in different locations, then stealing the plans would have been more difficult. The rebels would have had to breach security in all locations to steal the complete Death Star blueprints.
Maintainability vs Performance
Maintainability is an attribute that reflects how difficult and expensive it is to make changes to a system after it has been released to customers. - You improve maintainability by building a system from small self-contained parts, each of which can be replaced or enhanced if changes are required. - In architectural terms, this means that the system should be decomposed into fine-grain components, each of which does one thing and one thing only. - However, it takes time for components to communicate with each other. Consequently, if many components are involved in implementing a product feature, the software will be slower.
Availability vs Time-to-market
The availability of a system is a measure of the amount of 'uptime' of that system. - Availability is normally expressed as a percentage of the time that a system is available to deliver user services. - Availability is particularly important in enterprise products, such as products for the finance industry, where 24/7 operation is expected. Architecturally, you achieve availability by having redundant components in a system - To make use of redundancy, you include sensor components that detect failure, and switching components that switch operation to a redundant component when a failure is detected. - Implementing extra components takes time and increases the cost of system development. It adds complexity to the system and therefore increases the chances of introducing bugs and vulnerabilities.
Software Architecture
The fundamental organization of a software system embodied in its components, their relationships to each other and to the environment, and the principles guiding its design and evolution. - The architecture of a software product affects its performance, usability, security, reliability and maintainability.
Designing iLearn as a service-oriented system
These principles led us to an architectural design decision that the iLearn system should be service-oriented. - Every component in the system is a service. Any service is potentially replaceable and new services can be created by combining existing services. Different services delivering comparable functionality can be provided for students of different ages. Service integration - Full integration Services are aware of and can communicate with other services through their APIs.- Partial integration Services may share service components and databases but are not aware of and cannot communicate directly with other application services. - Independent These services do not use any shared system services or databases and they are unaware of any other services in the system. They can be replaced by any other comparable service.
Security vs Usability
You can achieve security by designing the system protection as a series of layers - Layers might include system authentication layers ,a separate critical feature authentication layer, an encryption layer and so on. - Architecturally, you can implement each of these layers as separate components so that if one of these components is compromised by an attacker, then the other layers remain intact.
Software Reuse
You can save a lot of time and effort if you can reuse large components from other products or open-source software. - However, this constrains your architectural choices because you must fit your design around the software that is being reused.