Software Architecture with Spring 5.0 - René Enríquez - E-Book

Software Architecture with Spring 5.0 E-Book

René Enríquez

0,0
39,59 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

Spring 5 and its ecosystem can be used to build robust architectures effectively. Software architecture is the underlying piece that helps us accomplish our business goals whilst supporting the features that a product demands. This book explains in detail how to choose the right architecture and apply best practices during your software development cycle to avoid technical debt and support every business requirement. Choosing the right architecture model to support your business requirements is one of the key decisions you need to take when a new product is being created from scratch or is being refactored to support new business demands. This book gives you insights into the most common architectural models and guides you when and where they can be used. During this journey, you’ll see cutting-edge technologies surrounding the Spring products, and understand how to use agile techniques such as DevOps and continuous delivery to take your software to production effectively. By the end of this book, you’ll not only know the ins and outs of Spring, but also be able to make critical design decisions that surpass your clients’ expectations.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB
MOBI

Seitenzahl: 356

Veröffentlichungsjahr: 2018

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Software Architecture with Spring 5.0

 

 

Design and architect highly scalable, robust, and high-performance Java applications

 

 

 

 

 

 

 

 

 

 

René Enríquez
Alberto Salazar

 

 

 

 

 

 

 

 

 

 

BIRMINGHAM - MUMBAI

Software Architecture with Spring 5.0

Copyright © 2018 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

Commissioning Editor: Richa TripathiAcquisition Editor: Sandeep MishraContent Development Editor: Anugraha ArunagiriTechnical Editor: Subhalaxmi NadarCopy Editor: Safis EditingProject Coordinator: Ulhas KambaliProofreader: Safis EditingIndexer: Aishwarya GangawaneGraphics: Tom ScariaProduction Coordinator: Shraddha Falebhai

First published: August 2018

Production reference: 1310818

Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.

ISBN 978-1-78899-299-2

www.packtpub.com

  
mapt.io

Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.

Why subscribe?

Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals

Improve your learning with Skill Plans built especially for you

Get a free eBook or video every month

Mapt is fully searchable

Copy and paste, print, and bookmark content

PacktPub.com

Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.

At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.

Contributors

About the authors

René Enríquez works as technical leader in a multinational company headquartered in Silicon Valley. He worked on different projects using Java Enterprise Edition and Spring Framework. He currently works with different Spring projects to maintain legacy code and write microservices applying best practices to deliver products using Agile techniques with a strong focus on testing at different levels. During the last years, he worked as a software consultant for private and government companies and as an instructor of courses to develop enterprise and mobile applications. He was also a speaker at the ScrumDay and JavaDay conferences in Quito-Ecuador.

 

Alberto Salazar is an entrepeneur, passionate Java consultant, JUG leader, Auth0 ambassador and founder of the Java User Group of Ecuador, an associate member of the Java community process and a Java evangelist/trainer. He founded a consulting company in Latin America 10 years ago, where he creates and offers technical solutions based on Java. He has been working for 2 decades creating higly scalable and transactional systems. He is a regular speaker at multiple Java conferences and meetings. He recently organized a Java Conference in Ecuador with Java Champions and co-organized a Java Hackdays event in Spanish that brought together 11 different cities from around the world and 9 Spanish-speaking countries.

About the reviewer

Yogendra Sharma is a developer with experience in the architecture, design, and development of scalable and distributed applications. He was awarded a bachelor's degree from Rajasthan Technical University in computer science with a core interest in microservices and Spring. He also has hands-on experience in technologies such as AWS Cloud, Python, J2EE, NodeJS, Angular, MongoDB, and Docker. He is currently working as an IoT and cloud architect at Intelizign Engineering Services. He constantly explores technical novelties, and is open-minded and eager to learn about new technologies and frameworks. He has also technically reviewed books and video courses for Packt.

 

Roland Alden has been the founder as well as co-founder of three technology startups and has decades of experience managing software engineering teams distributed around the world (Armenia, China, India, Micronesia, Nigeria, Pakistan, UAE, Ukraine, and Zambia). His background includes large companies (Data General and AT&T) and venture capital backed startups (Forethought, Go, and Eo). Currently, he works at ioet Inc., a software outsourcing firm based in Silicon Valley and Ecuador. He is a co-author of the Working with Computers and Working with Microsoft Office series of textbooks published by Houghton Mifflin.

 

 

 

 

Packt is searching for authors like you

If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.

Table of Contents

Title Page

Copyright and Credits

Software Architecture with Spring 5.0

Packt Upsell

Why subscribe?

PacktPub.com

Contributors

About the authors

About the reviewer

Packt is searching for authors like you

Preface

Who this book is for

What this book covers

To get the most out of this book

Download the example code files

Download the color images

Conventions used

Get in touch

Reviews

Software Architecture Today

Defining software architecture

I know my land

I want to stay ahead

Predicting the future

Architecture and architects

Software architecture principles

Components

Low coupling

High cohesion

SOLID principles

The single responsibility principle (SRP)

The Open–Closed Principle (OCP)

The Liskov substitution principle 

The interface segregation principle (ISP)

The dependency inversion (DI) principle

Conway's law

Choosing the right technology for you

New trends 

Summary

Software Architecture Dimensions

Dimensions

The business dimension

Managing user requirements

Identifying and tracking business metrics

The data dimension

The technical dimension

The operations dimension

How to deploy an application

How interaction occurs among your components

Dealing with infrastructure

Understanding the infrastructure

Versioning

Testing

Cloud versus on-premise

Deploying your application

The C4 model

Context diagram

Container diagram

Components diagram

Class diagram

Summary

Spring Projects

Why Spring appeared

Spring projects

Spring Initializr

Spring Boot in a Nutshell

Servlet container integration

Autoconfiguration

Dependency management

mvnw and mvnw.cmd

pom.xml

DemoApplication.java

The application.properties file

DemoApplicationTests.java

Avoiding redeployment with developer tools

Spring Data

Supporting EIPs with Spring Integration

Spring Batch

The read step

The process step

The write step

Securing applications with Spring Security

Embracing (Spring) HATEOAS

Spring Cloud and the microservices world

Configuration server

Service registry

Edge services

Microproxy

API gateway

Circuit breaker

Reactive and Spring

Publisher

Subscriber

Subscription

Processor

Project reactor

Mono

Flux

Back pressure

Reactive Spring Data

Reactive REST services

Summary

Client-Server Architectures

Understanding client-server architectures

Server

Scaling 

Request

Client

Network

Where to apply client-server architectures

Implementing client-server architectures with Spring

The server

SOAP web services

RESTful web services

CORBA

Sockets

AMQP

Implementing the server

Banking-domain

Banking-api

Boundaries

Domain

Persistence

Service

Monitoring the server

Testing

Banking-client

Authentication endpoint client

Account balance endpoint client

The clients

JavaFX client

Android client

Thin client

Summary

Model-View-Controller Architectures

MVC

The Model (M)

The View (V)

The Controller (C)

Benefits of using MVC 

Common pitfalls

Implementing applications using MVC

Spring MVC

Testing

Test coverage

UI frameworks

Thymeleaf

Securing an MVC application

Basic authentication

Implementing basic authentication

Summary

Event-Driven Architectures

Underlying concepts and key aspects

Command

Event

Patterns of event-driven architectures

Event notification

Event-carried state transfer

Improving application performance

Reducing the load on the source application

Increasing the availability of the system

Event sourcing

CQRS

Complex domain models

Distinct paths to query and persist information

Independent scaling

Summary

Pipe-and-Filter Architectures

Introducing Pipe-and-Filter concepts

Filters

Pipes

Boarding Pipe-and-Filter architectures

Use cases for Pipe-and-Filter architecture

Spring Batch

Implementing pipes with Spring Batch

Summary

Microservices

Principles of microservices

Size

Autonomous

Working well together

Advantages

Alignment to the single responsibility principle

Continuous releases

Independent scalability

Increased adoption of new technologies

Drawbacks

Too many options

Slow at the beginning

Monitoring

Transactions and eventual consistency

Modeling microservices

Speeding up

Accelerating the development process

Embracing tests

Going to production

Implementing microservices

Dynamic configuration

Implementing a configuration server

Implementing a configuration client

Service discovery and registration

Introducing Eureka

Implementing a Netflix Eureka service registry

Implementing a service registry client

Netflix Ribbon

Edge services

Introducing Zuul

CAP theorem

Consistency

High availability

Partition tolerance

Circuit breaker

Hystrix

Summary

Serverless Architectures

An introduction to serverless architecture

Infrastructure and file storage

Benefits and pitfalls

Backend as a service

Function as a service

Concerns about serverless architectures

Vendor lock-in

Security

Framework support

Troubleshooting

Examples and common use cases

Adopting serverless architectures for SPA 

Implementing FaaS with Spring Cloud Functions

Functions with Spring

Coding the example

Adapters

AWS Lambda adapter

Azure adapter

Summary

Containerizing Your Applications

Containers

Basic concepts

Containers and images

Basic commands

Running containers

Working with containers

Working with images

Building your own images

FROM command

MAINTAINER command

RUN command

ENV command

EXPOSE command

CMD command

Containerizing applications

Docker Gradle plugin

Registries

Publishing images

Provisioning multiple-container environments

Docker Compose

Linking containers

links

depends_on

Container orchestration with Kubernetes

Pod

Labels

Replication controllers

Services

Summary

DevOps and Release Management

Silos

How to break silos

DevOps culture

Motivations

DevOps adoption

Embracing automation

Infrastructure as code

Spring application and DevOps practices

Supporting different environments

Selecting profiles

Vagrant

Working with Vagrant

Release management

pipelines

Continuous integration

Continuous delivery and continuous deployment

Automating pipelines

Jenkins

Summary

Monitoring

Monitoring

Monitoring Spring applications

Application Performance Management (APM) tools

New Relic

Summary

Security

Why security is important as a part of an application's architecture

Key security recommendations

Authentication and authorization

Cryptography

Data input validation

Sensitive data

Social engineering

OWASP Top 10

Penetration testing

Authentication and authorization as a service

Summary

High Performance

Why performance matters

Scalability

Horizontal scalability

Vertical scalability

High availability

Performance

The key recommendation to avoid performance issues

Identifying bottlenecks

Profiling applications 

Visual VM

SQL query optimizations

A load test example

Summary

Other Books You May Enjoy

Leave a review - let other readers know what you think

Preface

Today we count on different software architecture styles that can be applied in different scenarios. In this book, we will review the most common software architecture styles and how they can be implemented using Spring Framework, which is one of the most widely adopted frameworks within the Java ecosystem.

At the beginning, we'll review some key concepts inherent to software architecture in order to understand the fundamental theory before diving into technical details.

Who this book is for

This book is aimed at experienced Spring developers who are aspiring to become architects of enterprise-grade applications and at software architects who would like to leverage Spring to create effective application blueprints.

What this book covers

Chapter 1, Software Architecture Today, provides an overview of how software architectures are managed today and why they are still important. It discusses how the most recent needs of the software industry are handled by the new emerging architecture models and how they can help you to solve these new challenges.

Chapter 2, Software Architecture Dimensions, reviews the dimensions associated with software architectures and how they influence the building process of your applications. We will also introduce the C4 model used to document software architectures.

Chapter 3, Spring Projects, speaks about some of the most useful Spring Projects. It's important to know which tools are inside your toolbox because Spring provides a wide variety of tools that fit your needs and can be used to boost your development process.

Chapter 4, Client-Server Architectures, covers how client-server architectures work and the most common scenarios where this style of architecture can be applied. We will go through various implementations, starting from simple clients such as desktop applications to modern and more complex usages such as devices connected to the internet.

Chapter 5, MVC Architectures, speaks about MVC, which is one of the most popular and widely known architecture styles. In this chapter, you will get an in-depth understanding of how MVC architectures work.

Chapter 6, Event-Driven Architectures, explains the underlying concepts related to event-driven architectures and which issues they handle using a hands-on approach.

Chapter 7, Pipe-and-Filter Architectures, focuses heavily on Spring Batch. It explains how to build pipelines, which encapsulate an independent chain of tasks aimed to filter and process big amount of data.

Chapter 8, Microservices, provides an overview about how to implement microservice architectures using the spring cloud stack. It details every component and how they interact with each other in order to provide a fully functional microservice architecture.

Chapter 9, Serverless Architectures, speaks about many services on the internet that are ready-to-use and can be used as part of software systems, allowing companies to just focus on their own business core concerns. This chapter shows a new way to think about building applications around a series of third-party services to solve common problems such as authentication, file storage, and infrastructure. We will also review what FaaS approach is and how to implement it using Spring.

Chapter 10, Containerizing Your Applications, explains that containers are one of the most handy technologies used in the last few years. They help us to get rid of manual server provisioning and allow us to forget the headaches related to building production environments and the maintenance tasks for servers. This chapter shows how to generate an artifact ready for production that can be easily replaced, upgraded, and interchanged eliminating the common provisioning issues. Through this chapter, we will also introduce container orchestration and how to deal with it using Kubernetes.

Chapter 11, DevOps and Release Management, explains that Agile is one of the most common approaches to organizing teams and making them work together to build products more quickly. DevOps is an inherent technique of these teams, and it helps them to break unnecessary silos and boring processes, giving teams the chance to be in charge of the whole software development process from writing code to deploy applications in production. This chapter shows how to achieve this goal by embracing automation to reduce manual tasks and deploy applications using automated pipelines in charge of validating the written code, provisioning the infrastructure, and deploying the required artifacts in a production environment.

Chapter 12, Monitoring, explains that once the application is published, unexpected behaviors are not uncommon and that it's essential to notice them so that they can be fixed as quickly as possible. This chapter gives some recommendations regarding techniques and tools that can be used to monitor the performance of an application bearing in mind technical and business metrics.

Chapter 13, Security, explains that often security is one of the fields that teams do not pay close attention to when they are working on developing their products. There are a few key considerations that developers should keep in mind when they are writing code. Most of them are pretty obvious, while others aren't, so we will discuss all of them here.

Chapter 14, High Performance, explains that there is nothing more disappointing in a job than dealing with issues in production when an application is behaving in an unexpected way. In this chapter, we'll discuss some simple techniques that can be applied to get rid of these annoying problems by applying simple recommendations on a daily basis.

To get the most out of this book

A good understanding of Java, Git, and Spring Framework is necessary before reading this book. A deep knowledge of OOP is desired, although some key concepts are reviewed in the first two chapters.

Download the example code files

You can download the example code files for this book from your account at www.packtpub.com. If you purchased this book elsewhere, you can visit www.packtpub.com/support and register to have the files emailed directly to you.

You can download the code files by following these steps:

Log in or register at

www.packtpub.com

.

Select the

SUPPORT

tab.

Click on

Code Downloads & Errata

.

Enter the name of the book in the

Search

box and follow the onscreen instructions.

Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:

WinRAR/7-Zip for Windows

Zipeg/iZip/UnRarX for Mac

7-Zip/PeaZip for Linux

The code bundle for the book is also hosted on GitHub athttps://github.com/PacktPublishing/Software-Architecture-with-Spring-5.0. We also have other code bundles from our rich catalog of books and videos available athttps://github.com/PacktPublishing/. Check them out!

Download the color images

We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://www.packtpub.com/sites/default/files/downloads/SoftwareArchitecturewithSpring5_ColorImages.pdf.

Get in touch

Feedback from our readers is always welcome.

General feedback: Email [email protected] and mention the book title in the subject of your message. If you have questions about any aspect of this book, please email us at [email protected].

Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.

Piracy: If you come across any illegal copies of our works in any form on the Internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.

If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.

Reviews

Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!

For more information about Packt, please visit packtpub.com.

Software Architecture Today

In this chapter, we will review what software architecture is and why it's still relevant today. We will also discuss the new business demands that have been guiding the world of software development in the last few years, and how they have affected the software industry as a whole.

Software and technology are evolving daily, introducing new demands that businesses must meet in order to remain relevant in a competitive market. Regardless of their core business, every competitive company has had to turn to technology. Online transactions and clients around the world are just some of the challenges that have to be mastered in order to stay ahead.

In order to support these new demands, we have been discovering new ways to do our work. Drastic changes have been made and adopted, directly affecting our software development life cycle (SDLC). Some examples of these changes are reflected in how we work on the following phases:

Gathering requirements

Organizing teams

Designing software architectures

Writing code

Deploying applications

In this chapter, we will start by revisiting the underlying concepts of software architecture, which have been present for a long time and are still relevant today.

This chapter will cover the following topics:

Defining software architecture

Common 

mistakes that are made when creating architecture

s

Architecture and architects

Software architecture principles

Applying high cohesion and low coupling in order to create components

SOLID principles

Conway's law

Choosing the right technology for you

New technology tendencies

Defining software architecture

No matter whether or not someone holds the software architect role in a team, every application has an architecture that somebody needs to take care of. This is an important step as it helps us to avoid writing entangled code, which makes a software system impossible to evolve in the future.

First things first: In order to know why you need to remember software architecture, we first need to understand what it is and why it is important.

In software, the term architecture is hard to define. Authors often borrow the definition from the construction industry, which is wrong. Software architecture is not all about diagrams, such as plans for buildings or houses—it's more than that. It's about the shared knowledge that technical and even nontechnical people have about the application that the whole team is creating, how the modules are connected to shape it, and all the complicated and vital elements surrounding it. Good software architectures are heavily focused on business requirements rather than on frameworks, programming languages, diagrams, and programming paradigms. Of course, we need these because we create applications using them. However, they don't have to define the underlying principles that dictate how we conceive the software. Instead, this role should be played according to business requirements.

The long-term success of an application is mainly based on its architecture, which must be created to support a well-defined set of business requirements, as mentioned earlier. Since an application needs to resolve these specific requirements, they must guide the architecture of the application. However, there are two main scenarios in which we guide software architecture decisions based on technology instead of business requirements:

I know my land

I want to stay ahead

I know my land

This scenario occurs when we create software architectures using frameworks and programming languages that we already know about, without paying close attention to business needs.

Let's say that the ABC company needs an application for manipulating text from large log files. If someone were to ask to work on this requirement, then they will choose a programming language that they are comfortable with during the development process, instead of looking for the best approach elsewhere.

Imagine that the person in charge of creating this application has already mastered JavaScript. In this case, do you think it's a good idea to write code using Node JS or another JavaScript framework running on the server in order to write an application to manipulate log files? I'm not saying that this is impossible—you can do it. However, do you think an application created using this approach will be able to perform and scale better than a system written in Perl, Python, or C, for example? This is not to say that JavaScript is terrible—it is simply important to know that this approach is not a good fit for JavaScript.

I want to stay ahead

We all want to stay ahead with technology, using the latest trends in the programming world to have a better technological background and consequently land cool jobs. Some people tend to write applications, keeping this idea in mind. Let's explain this scenario using the application example for manipulating log files that we mentioned in the previous section.

Suppose you're asked to solve the problem that we mentioned in the I know my land section. In this scenario, your only concern is technology. For instance, let's say you want to try the newest features in the latest PHP release. In this case, you will build this application using PHP. While this programming language has been improving over the last few years since Facebook started to add new features to it, the idea behind writing an application to manipulate large log files using PHP is crazy. As you may know, this programming language is intended to create other kinds of applications—mainly those that have to be accessed using a web browser and without high transactional requirements.

Again, you can write an application using PHP to manipulate large log files, but what will happen when more features are needed? Do you think a software architecture created with this approach in mind will be able to respond quickly to new requirements and the inherent characteristics of the application used in this example?

Predicting the future

While we can't predict each detail of an application when we are creating it, we can keep some apparent assumptions in mind to avoid glaring mistakes, like the ones exposed in the preceding sections. Even if you have created an application using the wrong approach, one part of the software architecture process is to evaluate the code base from time to time and take corrective actions based on this. This is important because the existing software architecture needs to evolve in order to avoid becoming useless. During the development process—and because we do not want to miss the established project deadlines—weoften use the FIXMEandTODOtags. However, we should pay close attention to these and take action as soon as we can, as they represent a technical debt that gets worse as time passes. Imagine how easy it is to get rid of a recently introduced debt in the next iteration. Now, imagine how hard it would be if the developer who added that debt is no longer working on the project or even within the same company.

Remember that these tags represent a debt, and debts are paid with interest that increases with time.

The process of improving the existing software architecture sometimes tends to be even more interesting than creating a new one from scratch. This is because you now have more information about the business requirements and how the application was performing at the time that it was in production.

When you are adding new features to an existing application, you will figure out how good the initial idea was. If the process of adding new features is simple and requires only a few changes in its structure, then we can conclude that the software architecture is doing its job well. Otherwise, if we need to make substantial changes to the underlying parts of the original design, we can say that the initial idea and assumptions were all wrong. However, at this point, the team in charge of the product should be responsible enough to make it evolve instead of writing additional patches to support new features.

Even though patching something sounds similar to making it evolve, it isn't. This idea is explained clearly in the book Building Evolutionary Architectures, written by Neal Ford, Rebecca Parsons, and Patrick Kua.

Proactive teams continually apply changes that make it possible to better support preexisting and new features rather than simply sitting and waiting for chaos when things get out of control. There's nothing wrong with changing an initial design, and it's always worth doing this. The following diagram illustrates this process, as applied to a geometric shape:

Evolving original designs

Now that we know that business needs must guide the application architecture, we can conclude that if it is unable to support new features, then new business opportunities will be missed, making the application and its architecture useless.

Architecture and architects

Before the agile and DevOps approaches appeared, architects used to focus on creating standards and rules to write code. In the past, it was common to find architects who wrote code, but this approach is currently outdated with regards to programming. Over the last few years, the idea of architects has been disappearing, all thanks to the new emerging models for creating teams. Agile movements have been in the software industry for a while, helping us to rethink how we are building software and organizing teams.

Nowadays, it's almost impossible to find software teams that have an architect working with them. Moreover, the idea of having different groups of people as part of an organization that collaborates using a silo style (where one task has to be finished before starting a new one) is disappearing. A few years ago, we had well-defined roles and even specialized departments for the following roles:

Business analysts

Developers

QA engineers

Architects

DBAs

People working on infrastructure 

Operations

Security

The following graphic shows how teams work using a silos style:

Teams working as silos

The preceding list also grows in specific cases. Teams working using a silo style used to work on producing defined artifacts, such as documentation, UML diagrams, and other things that are usually incomplete.

This approach is changing, and having small and multidisciplinary teams in charge of taking care of every single detail of an application is now more common. This approach has helped to create proactive teams with strong skills that allow us to ensure that software architecture is still happening all the time.

It's evident that not every team member has the full set of skills required to work on every stage, from gathering requirements to deploying the application in production, but the communication among all of them allows us to reduce the technical gaps and have a better understanding of the bigger picture of the application. This is one of the most important aspects of software architecture.

This shared knowledge helps the team to continue improving the existing software architecture, overcoming the most complex problems. All of the teams in charge of writing software can understand the details of the system under development instead of delegating this responsibility to only one person or even to a department. This approach can lead us to rely on people or teams that would be slightly out of the business context of why the application was being created. This is because people that worked on the project in the past but no longer participate actively due to working on more than one project can't fully understand all of the details of every system.

Software architecture principles

Software architecture should improve by following two simple principles that are often difficult to achieve:

Low coupling

High cohesion

No matter what programming language, paradigm, or tools you are using to architect your applications, these two principles should guide you when building your software architecture components.

In order to build the components that will shape your architecture, it's always worth following the guidelines. These are still relevant, even after many years of existence, and they should always be considered when components are being created. In this section, I'm talking about SOLID principles and Conway's law, which we will discuss in more detail later in this chapter. It is now time to look at what components are in more detail.

Components

A component is a set of functions, data structures, and algorithms that solve one problem. This means that all the code and artifacts that are used to build the component have a high cohesion with each other; the rule here is that the classes or files that create a component should change at the same time and for the same reason.

Software architecture is built using many components, and you should not be worried about having an excessive quantity of these. The more components you write, the more freedom there is to assign them to different developers or even to different teams. Large software architectures can be created using many smaller components that can be developed and deployed independently of each other.

Once we connect these components to each other, they allow us to create the desired software architecture.

As shown in the following diagram, we can see the components as pieces of a puzzle that come together to form an application:

Components forming a larger application

The connected components define application architectures, and their designs describe how each component has been created internally. It's here that pattern designs and SOLID principles must be used to create good designs.

High cohesion

The principle of high cohesion also has a pretty simple definition: one component should perform one and only one well-defined job. Although the description is pretty simple, we often tend to get confused and violate this principle.

In the previous example, we had NotificationService, which was in charge of sending notifications by email and fax. The word and can be helpful for us when it comes to identifying the violation of this principle. Now that we have two different classes (one per notification channel), it's fair to say that our classes only have one responsibility.

Again, the same is true for components, and another reason to keep the same idea with them is that you will likely have each component accomplishing only one specific requirement. For example, what would happen if all our customers just wanted to receive their bank statements by email; do you think it's okay to depend on a class that has the ability to send faxes too?

Although the previous question may seem unimportant, imagine that you solved an existing issue related to sending notifications using faxes as a notification mechanism, and a new issue was then introduced into the mechanism in order to send email notifications by mistake.

Remember that components shape your software architecture, and architects should design them in a way that maximizes team productivity. Aligning your components to the high-cohesion principle is an excellent way to separate them and allows teams to work independently on different parts of your application. This ability to create various components with clear responsibilities will make it easier when solving other issues and adding new features, and will also make you less prone to introducing bugs.

With regards to the previous example, you are probably wondering why the NotificationChannel class is apparently sending notifications with a BankStatement parameter.

Common sense leads us to believe that we need to replace this class with any other generic type. It can be helpful to allow the application to send different kinds of notifications, and not only bank statements: this may include drawbacks, or when a new deposit is received in the account. Even though the idea of supporting incoming requirements looks like something you might want to include in the program at this stage, the application doesn't currently need this ability. This is why it is not necessary for us to add this feature right now. Instead, this design should evolve when this becomes necessary; in this way, we are sticking to the KISS principle (https://www.techopedia.com/definition/20262/keep-it-simple-stupid-principle-kiss-principle) and following the directions of only building the most basic features to make the application work.

SOLID principles

SOLID is an acronym that represents the five underlying principles that guide a good software design. The design is related to the creation of components that shape your software architecture.

In 2004, Michael Feathers suggested this acronym to Robert C. Martin, the author of these principles. The process for creating them took him around 20 years, and during this period, many of them were added, removed, and merged to achieve a robust set of principles named SOLID. Let's review each one of the principles and provide a brief and clear explanation that will be helpful for getting a precise idea of how we can use them.

We will use the term module in tandem with the idea of modules shaping components, and we will make reference to the object-oriented programming (OOP)world using terms such as classes and interfaces in order to provide a more precise explanation of modules.

The single responsibility principle (SRP)

The SRP is very closely related to the high cohesion that we reviewed earlier. The idea behind this principle is that a module should be changed for one reason only. 

This definition leads us to conclude that a module should have only one responsibility. One way to verify whether this principle is achieved in your design is to answer the following questions:

Does the module's name represent its exposed functionality?