Software Architecture For Developers Sample
Software Architecture For Developers Sample
with agility
Software Architecture for Developers - Volume 1
Simon Brown
This book is for sale at http://leanpub.com/software-architecture-for-developers
This is a Leanpub book. Leanpub empowers authors and publishers with the Lean
Publishing process. Lean Publishing is the act of publishing an in-progress ebook using
lightweight tools and many iterations to get reader feedback, pivot until you have the right
book and build traction once you do.
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv
I Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1. What is “software architecture”? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Architecture as a noun - structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Architecture as a verb - vision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Types of architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Towards a definition of “software architecture” . . . . . . . . . . . . . . . . . . . . 7
Enterprise architecture - strategy rather than code . . . . . . . . . . . . . . . . . . . 8
Architecture vs design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Is software architecture important? . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Does every software project need software architecture? . . . . . . . . . . . . . . . 13
II Architects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
No wonder it’s hard to find a single definition! Thankfully there are two common themes
here: architecture as a noun and architecture as a verb.
and outside of the immediate software development team, so that everybody has a consistent
view of what is being (or has been) built. The process of architecting is additionally about
introducing technical leadership so that everybody involved with the construction of the
software system is able to contribute in a positive and consistent way.
Types of architecture
What we have so far is a very generic definition of the word “architecture” but, of course,
there are many different types of architecture and people who call themselves “architects”
within the IT industry. Here, in no particular order, is a list of types of architecture that
people most commonly identify when asked.
• Infrastructure
• Security
• Technical
• Solution
• Network
• Data
• Hardware
• Enterprise
• Application
• System
• Integration
• IT
• Database
• Information
• Process
• Business
• Software
The unfortunate thing about this list is that some of the terms are easier to define than
others, particularly those that refer to or depend upon each other for their definition. For
example, what does “solution architecture” actually mean? For some organisations “solution
architect” is simply a synonym for “software architect”, whereas other organisations have a
specific role that focusses on designing an overall “solution” to a problem, stopping before
What is “software architecture”? 5
the level at which implementation details are discussed. Similarly, “technical architecture”
is vague enough to refer to software, hardware or a combination of the two².
What do all of these terms have in common? Well, aside from being able to suffix each of
the terms with “architecture” or “architect”, all of these types of architecture have structure
and vision in common.
Let’s take “infrastructure architecture” as an example. Imagine that you need to create a
network between two offices located at different ends of the country. One option is to find
the largest reel of network cable that you can, plug it in at one office, and start heading to the
other in a straight line. Assuming that you had enough cable, this could potentially work. In
reality though, there are a number of environmental constraints (real-world obstacles such
as rivers, lakes, roads, cities, etc) and service-level agreements (performance, bandwidth,
security, etc) that you need to consider in order to actually deliver something that satisfies
the original goal. This is where the process of architecting is important. One single long
piece of cable is certainly one approach, but it’s not a very good one because of the real-
world constraints. For this reason, networks are typically much more complicated, requiring
a collection of smaller building blocks that collaborate together in order to satisfy the goal.
From an infrastructure perspective then, we can talk about structure in terms of the common
building blocks that you would expect to see within this domain; things like routers, firewalls,
packet shapers, switches, etc.
Regardless of whether you’re building a software system, a network or a database; a
successful solution requires you to understand the problem and create a vision that can
be communicated to everybody involved with the construction of the end-product. In order
to move towards a definition of “software architecture”, let’s look at a couple of types of
architecture in the IT domain that are relatively well defined.
Application architecture
Application architecture is what we as software developers are probably the most familiar
with. In this context, I’m going to define an application as being a single deployable unit,
written in a single technology; such as a single-page JavaScript/Angular application, an iOS
or Android mobile app, a Java server-side Spring MVC web application, a .NET desktop
application, etc.
Application architecture is about looking inside the application to understand how it’s
designed and built. This includes how the application has been decomposed into building
²My own job title for a number of years was “Technical Architect”. With hindsight, this was not very descriptive or accurate,
since my day-to-day focus was primarily software architecture rather than anything else.
What is “software architecture”? 6
blocks (e.g. components, layers, packages, namespaces, etc) as well as understanding the
patterns, frameworks and libraries in use. In essence, it’s predominantly about code, and the
organisation of that code.
System architecture
I like to think of system architecture as one step up in scale from application architecture. If
you look at most software systems, they’re actually composed of multiple deployable units
(e.g. applications or datastores), each of which might be built using different technologies.
As an example, you might have a software system comprising of a client-side iOS mobile
app communicating via JSON/HTTPS to a Java server-side Spring MVC web application,
which itself consumes data from a MySQL database. Since each of these three deployable
units (the mobile app, the web app and the database) is built using a different technology,
each of them will have their own internal application architecture.
However, for the software system to function as a whole, thought needs to be put into
bringing all of those separate deployable units together. In other words, you also need to
consider the overall structure of the software system at a high-level, and the integration of
the various parts. For example, if I make a request from the mobile app, how is that request
processed by the entire software system? Additionally, software systems typically don’t live
in isolation, so system architecture also includes the concerns around interoperability and
integration with other systems within the environment.
Where application architecture tends to focus primarily on software (e.g. programming
languages, frameworks, libraries, etc), system architecture is about understanding both
software and hardware. Admittedly, much of the hardware that we deal with nowadays
is virtualised or completely hidden³, but it’s an important concern nonetheless. The reason
that most definitions of system architecture include references to software and hardware
(whether it’s the target deployment platform or supporting infrastructure) is that you can’t
have a successful software system without it. After all, software needs to be deployed
somewhere in order to run! Additionally, infrastructure typically provides constraints that
must be taken into account when designing software. Examples of this range from the
processing power and memory of embedded devices limiting what your software can do,
through to cloud providers limiting how your applications are deployed in order to facilite
better high availability and scaling.
³Platform as a Service (PaaS) and Function as a Service (FaaS) environments typically hide the underlying hardware completely,
and instead provide higher-level abstractions on which to build and deploy software systems. Understanding the constraints of these
environments is still important if you want to build software that “works”.
What is “software architecture”? 7
In order to think about these things, you need to step back, away from the code and your
development tools. Working software is ultimately about delivering working code, so the
detail is crucially important. But software architecture is about having a holistic view across
your software system, to ensure that your code is working toward your overall vision rather
than against it.
What is “software architecture”? 8
Architecture vs design
One of the words that people use to describe architecture is “design”, and this raises the
question of whether we should use the words “architecture” and “design” interchangeably.
What is “software architecture”? 9
Grady Booch has a well cited definition of the difference between architecture and design
that really helps to answer this question. In On Design, Grady says that:
If you think about any problem that you’ve needed to solve, there are probably a hundred
and one ways in which you could have solved it. Take your current software project/product
for example. There are probably a number of different technologies, deployment platforms,
and design approaches that are also viable options for achieving the same goal. In designing
your software system though, your team chose just one of the many points (options) in the
potential decision space. That’s the essence of design. It’s about narrowing down the solution
space to find an option that works given the context in which you are working.
Grady then goes on to say that:
This makes sense, because creating a solution, and “architecting”, is essentially a design
exercise. It’s about narrowing down options, and making decisions. However, for some
reason, there’s a distinction being made about not all design being “architecture”, which
Grady clarifies with the following statement:
Essentially, Grady is saying that the significant decisions are “architecture”, and that
everything else is “design”. In the real world, the distinction between architecture and design
isn’t clear-cut, but this definition does provide us with a basis to think about what might be
significant (i.e. “architectural”) in our own software systems. For example, this could include:
• The overall shape of the software system (e.g. client-server, web-based, native mobile,
distributed, microservices, asynchronous vs synchronous, etc).
• The structure of the code inside the various parts of the software system (e.g. whether
the code is structured as components, layers, features, ports and adapters, etc).
What is “software architecture”? 10
The architectural decisions are those that you can’t reverse without some degree of effort.
Or, put simply, they’re the things that you’d find hard to refactor in an afternoon.
Architectural significance
Although this sounds relatively straightforward, we, as architects, have a degree of influence
over those architecturally significant decisions. Imagine you’re building a simple server-side
web application to deliver information to users, and that information is stored in a relational
database. For the sake of this discussion, let’s say there are no complex requirements related
to security, performance or scalability, and that the database is simply being used for data
storage. Let’s also ignore non-relational (e.g. NoSQL) databases.
When building the web application, many teams will choose to use some sort of abstraction
layer to communicate with the database, like an object-relational mapping framework; such
as Hibernate, JPA, Entity Framework, etc. One common reason to use a database abstraction
layer is to make accessing the database easier. Another common reason to use a database
abstraction layer is to decouple business/domain-specific code from the choice of database.
The use of an abstraction layer is a classic technique for decoupling distinct parts of a
software system; promoting looser coupling, higher cohesion and a better separation of
concerns. If you’re only using the database for data storage (i.e. the database only contains
data rather than code wrapped up functions and stored procedures), the use of the database
abstraction layer allows you to, in theory, change your database via configuration, without
changing any code. Since the database can be changed so easily, many teams would therefore
consider the choice of database to no longer be a significant decision.
However, while the database may no longer be considered a significant decision, the choice
to decouple through the introduction of an additional layer should be. If you’re wondering
why, have a think about how long it would take you to swap out your current database
abstraction layer or web MVC framework and replace it with another. Of course, you could
add another layer over the top of your chosen database abstraction layer to further isolate
your business logic and provide the ability to easily swap out your database abstraction layer
but, again, you’ve made another significant decision. You’ve introduced additional layering,
complexity and cost.
What is “software architecture”? 11
Although we can’t necessarily make “significant decisions” disappear, we can use a number
of different tactics (such as architectural layering, in the previous example) to change what
those significant decisions are. There’s also no explicit line between the decisions that should
be deemed as significant, and those that shouldn’t. Having said that, the significant decisions
are usually related to key technology choices (e.g. programming languages and frameworks)
and the overall structure (monolithic deployment unit vs microservices). Aspects such as
“tabs vs whitespaces”, or “curly braces on same line vs the next line”, are definitely not
architecturally significant! Everything else will fall in between somewhere between these
two extremes. Part of the process of architecting a software system is about understanding
what is significant and why, given the context you’re working in.
slow, insecure, fragile, unstable, hard to deploy, hard to maintain, hard to change, hard to
extend, etc. I’ve personally seen (and worked on!) codebases that have exhibited the following
types of problems:
Additionally, without technical leadership, many codebases also end up looking like the
stereotypical “big ball of mud” or “spaghetti code”. Sure, it has a structure, but not one that
you’d want to work with! These seemingly chaotic software projects do exist in the real-
world, and most of us will have one or more horror stories about the time we spent working
on them. If you’ve never worked on such a project, you’re probably in the lucky minority!
Thankfully, most of these problems are relatively easy to solve with the application of some
good technical leadership, resulting in a team that therefore understands and thinks about
software architecture. In summary, this can provide:
• A clear vision and roadmap for the team to follow, regardless of whether that vision is
owned by a single person or collectively by the whole team.
• Technical leadership and better coordination.
• A stimulus to talk to people (inside and outside of the team) in order to ask questions
relating to significant decisions, quality attributes, constraints and other cross-cutting
concerns.
• A framework for identifying and mitigating risk.
What is “software architecture”? 13
Rather than use the typical consulting answer of “it depends”, I’m instead going to say
that the answer is undoubtedly “yes”. The caveat here is that every software team should
look at a number of factors in order to assess how much software architecture thinking,
a degree of which manifests itself as up front design, is necessary. These include the size
of the project/product, the complexity of the project/product, the size of the team and the
experience of the team.
Historically we’ve seen a tendency towards too much up front design, with teams trying
to answer all of the questions and solve all of the problems before writing a single line of
code. More recently, I’ve witnessed a trend towards the other extreme, and too little up front
design. As Dave Thomas once said:
As with many things in life, there is a sweet spot here awaiting discovery. The answer to
how much is “enough” up front design and technical leadership will be explored throughout
the rest of this book.
II Architects
This part of the book focusses on the software architecture role; including what it is, what
sort of skills you need, and why coding, coaching and collaboration are important.
2. The software architecture role
The line between being a software developer and being a software architect is a tricky one.
Some people will tell you that it doesn’t exist, with architecture just being an extension of
the design process undertaken by developers. Others will tell you that it’s a massive gaping
chasm, which can only be crossed by lofty developers who believe you must always abstract
your abstractions and not get bogged down by those pesky real-world implementation
details. As always, there’s a pragmatic balance somewhere in between, but it does raise
the interesting question of how you move from one side to the other, and therefore how you
progress in your career as a software developer.
As we learnt in chapter 1, software architecture is about a number of different things; ranging
from the organisation of code through to having a holistic view of the software system
being built from a number of different perspectives, and making the appropriate significant
design decisions to ensure success. This definition is necessarily broad, but it doesn’t really
describe what software architects do, and how a software developer moves into a software
architecture role. It also doesn’t help in identifying who will make a good software architect,
and how you go about finding them if you’re hiring.
Becoming a software architect isn’t something that happens overnight or with a promotion.
It’s a role, not a rank. It’s the result of an evolutionary process where you’ll gradually gain
the experience and confidence that you need to undertake the role. While the term “software
developer” is relatively well-understood, “software architect” isn’t. A simple way to think
about the software architecture role is that it’s about the “big picture” and, sometimes, this
means stepping away from the code.
Here are the things I consider to make up the software architecture role, with the summary
being that the role is about providing technical leadership and being responsible for the
technical success of the project/product. Notice that I said “role” here; it’s something that
can be performed by a single person or shared amongst the team, but we’ll talk about that
later.
The software architecture role 16
1. Architectural drivers
The first part of the role is about understanding, and managing, the architectural drivers
- the functional requirements, quality attributes, constraints and principles, as we saw in
the previous chapter. These driving forces have a huge influence on the resulting software
architecture, so explicitly including them as a part of the software architecture role helps to
ensure that they are proactively considered, and taken into account.
2. Designing software
It should come as no surprise that the process of designing software is a key part of the
software architecture role. This is about understanding how you’re going to solve the
problems posed by the architectural drivers, creating the overall structure of the software
system, and creating a vision for the delivery. Despite how agile you to strive to be, as we’ll
see later, you probably do need some time to explicitly think about how your architecture
is going to solve the problems set out by the various stakeholders.
A key part of designing software is technology selection, which is typically a fun exercise,
but it does have its fair set of challenges. For example, some organisations have a list of
approved technologies that you are “encouraged” to choose from, while others have rules
in place that don’t allow open source technology with a specific licence to be used. Then
you have all of the other factors such as cost, licensing, vendor relationships, technology
strategy, compatibility, interoperability, support, deployment, upgrade policies, end-user
environments, and so on. The sum of these factors can often make a simple decision of
The software architecture role 17
choosing something like a framework into a complete nightmare. Somebody needs to take
ownership of the technology selection and evaluation process, and this falls squarely within
the remit of the software architecture role.
3. Technical risks
What we’ve looked at so far will help you focus on building a good solution, but it doesn’t
guarantee success. Simply throwing together the best designs and technologies doesn’t
necessary mean that the overall architecture will be successful. There’s also the question
of whether the technology choices you’ve made will actually work. Many teams get burnt
because they believe the hype on vendor websites, or described by sales executives while
spending a few hours together on the golf course. I always find it surprising how few people
seem to ask whether a technology actually works the way it is supposed to, evaluating the
technology where needed to prove that this is the case. Technology selection is all about
managing risk; reducing risk where there is high complexity or uncertainty, and introducing
risk where there are benefits to be gained. All technology decisions need to be made by taking
many factors into account, and all technology decisions need to be reviewed and evaluated.
The key question that you need to ask yourself is whether your architecture “works”. For
me, an architecture works if it satisfies the architectural drivers, provides the necessary
foundations for the rest of the code, and works as the platform for solving the underlying
business problem. Software is complicated and abstract, which means that it’s hard to
visualise the runtime characteristics of a piece of software from a collection of diagrams,
or even the code itself. Furthermore, I don’t always trust myself to get it right first time.
Throughout the software development life cycle, we undertake a number of different types
of testing in order to give us confidence that the system we are building will work when
delivered. So why don’t we do the same for our architecture? If we can test our architecture,
we can prove that it works. And if we can do this as early as possible, we can reduce the
overall risk of project/product failure. Like good chefs, architects should taste what they
are producing. In a nutshell, the software architecture role is about proactively identifying,
mitigating, and owning the high priority technical risks so that your project doesn’t get
cancelled, and you don’t get fired.
4. Technical leadership
Whatever software architecture you create needs to be taken care of. Somebody needs to
look after it, evolving it throughout the delivery in the face of changing requirements and
The software architecture role 18
feedback from the team. If a software architect has created an architecture, they should own
and evolve that architecture throughout the rest of the delivery too. This is about continuous
technical leadership rather than simply being involved at the start of the life cycle and hoping
for the best.
5. Quality assurance
Even with the best architecture in the world, poor delivery can cause an otherwise successful
software project to fail. Quality assurance should be a part of the software architecture role,
but it’s more than just doing code reviews. You need a baseline to assure against, which could
mean the introduction of standards and working practices such as coding standards, design
principles and tools. Quality assurance also includes ensuring that the architecture is being
implemented consistently across the team. Whether you call this architectural compliance,
conformance or whatever is up to you, but any technical vision created by the people
performing the software architecture role needs to be understood and followed by the rest
of the team.
It’s safe to say that most projects don’t do enough quality assurance, and therefore you need
to figure out what’s important to make sure that it’s sufficiently assured. A good starting
point is to identify anything that is architecturally significant, business critical, complicated,
or highly visible. You need to be pragmatic though, and realise that you can’t necessarily
assure everything given the typical budgetary and time constraints we are subjected to.
Hi, I’ve just been promoted to be a software architect but I’m not sure what I
should be doing. Help! Which books should I read?
The software architecture role 19
Although I can’t stop organisations promoting people to roles above their capability (often
referred to as the Peter principle), I can describe what my view of the software architecture
role is, and help people achieve it.