# Software Architecture

## Summary


All good software has some structure to it. It's composed of components, each with well-defined functionality. It has interfaces, both internal (among components) and external (to its environment). Software architecture is about defining these aspects. It focuses on abstractions and hides implementation details.  More importantly, architecture is about capturing decisions, not just describing structures. 

Software architects take system requirements as inputs and produce various artefacts that describe the architecture. Both functional and non-functional requirements are considered. Architects make choices about architectural patterns, platforms, programming languages, databases, third-party libraries, tools, and more.

## Discussion

### How does software architecture differ from software design?

Architecture is about high-level abstractions whereas design is about low-level implementation details. Architecture helps us understand the system and how it's supposed to interact with its environment. It involves multiple stakeholders, presents an overall vision that meets quality attributes, and makes a clear separation of concerns. Software architects make choices and give reasons why those choices were made. Typically these choices are made early on in the project and are costly to change thereafter.  

In contrast, software design concerns itself with class methods/properties, data structures, algorithms, actual code, business logic, etc. Certain design methods play well with certain architectural styles. 

It's not easy to define what's high-level or important. They're very much contextual. Whatever these are, a good architect identifies them early on. Architecture is about reducing irreversibility: an architect defines what parts are fixed, what parts can be changed and attempts to minimize the former. Architecture is really a shared understanding of the system design.  

It's been said that "architecture is design but not all design is architectural". Dashofy defined, 

> A software system's architecture is the set of principal design decisions made about the system.


### Could you give examples of software architecture?

For a web application, an architect may define the main components: frontend, backend, storage, notifications, etc. She may decide to use Java, MySQL and Hibernate ORM. She may adopt the MVC pattern, or server-side rendering over client-side rendering. She may identify high-level components such as authentication, load balancer and CDN. She may even prescribe Eclipse IDE along with plugins Checkstyle, SonarLint and TestNG.

For an application server, we may use Java-EE. Functionality is spread across access layer, application processes layer and domain objects layer. Java-EE thus uses layered architecture. An alternative is the service-oriented architecture (SOA). This consists of a service bus to which producers and consumers connect via adapters. While Java-EE focuses on scalability and reliability, SOA focuses on integrability and modifiability. 

While there are API architects, in some projects the solution architect mandates an API gateway and developers detail the APIs. In a team of inexperienced developers, the architect may take on more design-specific tasks. 


### What are the key benefits of software architecture?

Creating a good architecture leads to right trade-offs, meeting requirements, reducing risks, and timely deliverables. Skipping architecture may save time towards short-term success. In the long term, rework and delays are quite likely. Poor architecture leads to technical debt, more defects and software that's harder to evolve. 

We often pay more for higher quality products. However, architecture doesn't exercise this quality-cost trade-off. Investing in architecture pays off within a few weeks. Without a proper architecture, we end up paying more later. Software that works as expected has external quality. Architecture is really **internal quality** that project teams should care about. 

Architecture helps maintain conceptual integrity of the system as it evolves. An architectural model is a living record of original decisions. As new features are added, such a model mitigates architectural drift. Architecture aids knowledge reuse and avoids "reinventing the wheel". 

Architecture can help modernize legacy systems such as migrating to the cloud or integrating AI/ML capabilities. Existing technical debt can be addressed or managed. 


### What are some patterns and frameworks in software architecture?

For common problems, there's no need to solve them from scratch. Architectural patterns can be adopted: client-server, peer-to-peer, event-driven, layered (n-tiered), space-based, service-oriented, microservices, serverless, cloud-native, microkernel, and many more. 

Ford and Richards have analysed and compared some of these patterns with respect to quality attributes. They published these as Architecture Styles Worksheet. For example, a microservices architecture rate higher on agility and fault-tolerance compared to layered architecture. But layered architecture is simpler and cheaper. 

Frameworks bridge concepts to coding blocks. As part of ISO/IEC/IEEE 42010:2011 work, ISO has been collating various architecture frameworks. There are frameworks for IoT, Big Data, security, management systems, communication systems, for the automotive industry, smart grids, and more. Indeed, **domain-specific reference architectures** are used in many industries. These lead to reusing architectures across products of a product line or family.  


### What artefacts does a software architect produce?

**Architecture model** is an essential artefact. It captures some or all of the architectural decisions. It's a tangible record of the architecture. Modelling could be informal (slides, diagrams), semi-formal (UML diagrams) or formal. Architecture Description Languages (ADLs) can be used for formal modelling. An ADL is a set of notations, languages, standards, and conventions. It can lead to formal analysis, evaluation, reuse, and automated code generation.  

Software systems can be viewed from different perspectives. Such views are complementary. An architect need to produce many of these views or diagrams: data flows, control flows, state transitions, entity relations, object-oriented hierarchies, data models, message sequences, and more. Another way to classify these views is logical, process, physical and development. 


### What processes are applicable for software architecture?

Software architecture is part of the overall discipline of software engineering. Architects need to interact with multiple stakeholders. They need to be clear about product requirements. Non-functional requirements include reliability, usability, efficiency, scalability, maintainability, and more. They should factor in additional constraints such as legal, regulations, costs, time-to-market and talent availability. 

Adopting a programming framework or developer tools such as Springboot or Cocoa implicitly selects an architecture. While developers can focus on design decisions, they need to be aware of the architectures they've adopted. Moreover, an architect needs to address runtime requirements including CI/CD, deployment, scalability and observability. 

Architects deal with architectural models, description languages, analysis techniques, development environments, canonical solutions, and design processes. Architecture establishes the constraints within which application components need to be developed. 

Static analysis of source code can be used to recover or reverse engineer the architecture of legacy systems. Such analysis can also identify deviations between architecture and implementation.  

It's foreseen that AI-enabled tools will automate architectural tasks. Decisions will become more data driven. Automated code generation and testing may help to quickly validate and refine architectures. 


### What are some pitfalls in software architecture?

Working without properly defining quality attributes leads to poor architecture. Asking vendors to create architectures or adopting architectures from another organization are just as bad: architecture needs context and tradeoffs depend on the context. Waiting for the perfect architecture before starting implementation is another pitfall. 

Even the best architecture can be ineffective if not properly communicated. Automated documentation, graphical views and change simulation are some tools that can help. Architects should communicate to upper management in a language they understand. Indeed, organizational structure should evolve to keep up with technological evolution. DevOps and CI/CD are useless if management takes weeks to approve a change. 

Architects shouldn't work in isolation. They should collaborate with everyone, looking out for problem areas before they become serious, giving their inputs, explaining the architecture, and mentoring individuals. These interactions create effective feedback loops towards architecture that's fit for purpose. 

Modelling tools are often inadequate when mapping the code to the model. Architects and their tools ignore software architecture evolution.  These limitations can result in drift between architecture and implementation.  Architecting should be continuous and an iterative process. 


### How can a developer move into the role of an architect?

Developers should move from their narrow focus of specific components or sub-systems. As architects, they should learn to look at the big picture and obtain a holistic view of the entire system. They should resist the urge to write code. A developer may focus on only coding but an architect has to look at requirements, coding, testing, deployments, evolution, and more. 

An architect should be able to take important decisions given the constraints and quality attributes. Because architects interface with many stakeholders, they need leadership qualities.  

Architects straddle both technical, business and interpersonal concerns. A solid technical background is essential for many tasks: spotting trends, planning, assessing risks, and critical thinking. An architect should have empathy and see things from a developer's perspective. This helps when reviewing and mentoring. Overall, an architect who's been a developer for many years and interacted with customers will do well. 

It's been said that software architect is not an independent role. Architecting should be regarded as a skill that developers and agile teams should practice. Architecting should be connected to developing. 


### What resources can help learn software architecture?

Two books published by SEI are *Software Architecture in Practice* and *Designing Software Architectures*. To learn about architectural patterns, see *Pattern-Oriented Software Architecture* by Buschmann et al. (1996). Richards has curated a list of books on software architecture. 

The SEI offers online courses on software architecture. There are also courses on Udemy and Coursera.

New architects can look at some templates of software architecture documents: Course Registration System and Co-op Evaluation System.

We may need to evaluate software architectures given a set of quality attributes. Some methods exist: Active Design Reviews, Software Architecture Analysis Method (SAAM), and Architecture Tradeoff Analysis Method (ATAM).  

## Milestones

1980

From the mid-1980s, practitioners of Software Engineering address architectural concerns to manage the complexity of large projects. They use box-and-line diagram as a tool. The decade ends with a DARPA workshop on the topic of Domain-Specific Software Architectures (DSSAs). 

1990

During this decade, architectural patterns, architecture description languages (ADLs), documentation, architecture recovery, tools, and formal methods are studied.  Design patterns and architectural styles aid teams with knowledge reuse. 

1992

Perry and Wolf publish a paper titled *Foundations for the study of software architecture*. This is perhaps the earliest use of the term "software architecture" in literature. 

1994

Garlan and Shaw of Carnegie Mellon University publish a paper titled *An Introduction to Software Architecture*. This includes a few architectural styles: pipes and filters, data abstraction and object-oriented organization, event-based, layered systems. In one case study, they propose and compare different styles. In 1996, they publish the book *Software Architecture: Perspectives on an Emerging Discipline*. This book brings together most ideas of the time. 

1995

The IEEE Software Engineering Standards Committee charters the **IEEE Architecture Planning Group (APG)**. It's objective is "to set the direction for the next generation of architecture-related standards and practices for the IEEE." Their work eventually results in the publication of IEEE 1471 Standard in 2000. Also in 1995, Taylor et al. publish *Software development using domain-specific software architectures*. 

Nov  
1995

Kruchten proposes the **"4+1" View Model**. The idea is that multiple views are necessary to address the concerns of different stakeholders. The four views are logical (object-oriented), process (synchronization, concurrency), physical (software-hardware mapping, distributed), and development (software organization) 

Sep  
2000

**IEEE 1471** titled *Recommended Practice for Architecture Description of Software-Intensive Systems* is approved as a standard. Traditionally, architects considered only hardware issues. This standard addresses this short-sightedness. In August 2001, ANSI makes this an American National Standard. In 2007, this is adopted by ISO/IEC as **ISO/IEC 42010:2007**. 

Nov  
2011

**ISO/IEC/IEEE 42010:2011** titled *Systems and software engineering — Architecture description* is published as an international standard. It's an evolution of IEEE 1471. This harmonizes ISO/IEC 42010, ISO/IEC 12207 and ISO/IEC 15288.