It’s difficult to find an exact definition for application architecture.
One could argue that it’s a subset of software architecture that primarily focuses on individual applications in contrast to, for example, enterprise architecture, which encompasses all the software inside a company including the interactions between different applications.
Application architecture is responsible for the high-level structure of an application which serves as a guideline or a blueprint for all the development work on that application.
Often people compare it to building architecture. However, there is a very important difference between the two.
Unlike buildings, software changes a lot and is never really ‘done’. This reflects in its architecture which also needs to constantly adapt to changing requirements and further development.
An application architecture should always be based on the requirements as specified by the stakeholders (business owners, users, etc.).
It’s important that this doesn’t include only functional requirements (i.e. what the application needs to do), but also the non-functional ones. The latter is concerned with application performance, reliability, maintainability and other aspects that don’t directly affect its functionality but have an impact on how the application is experienced by its users, developers and other stakeholders.
Editorial Note: Also read Software is Not a Building.
Aspects of application architecture
Architectural decisions are made at different levels.
Figure 1: Architectural decisions at different levels
Typically, the application architecture starts with the choice of the type of application to develop.
Is it going to be a web application, or will it run locally on a device (mobile or desktop)?
The choice will depend on multiple factors:
- Will the application be used on a computer, on a mobile phone, or both?
- Will the users always have internet connectivity, or will they use it in offline mode as well?
- Does the application take advantage of or even require the use of services and sensors available on devices, such as notifications, geolocation, camera, etc.
- …and so on.
Closely related to the choice of application type, is the choice of technology. Even if you’ve already decided on the .NET technology stack, there are still a lot of choices for all types of applications: desktop, mobile, and web.
You can read more about them in my previous articles for DNC Magazine:
Once you have decided on the application type and the technology stack, it’s time to look at the architectural patterns.
They have a role similar to design patterns, only that they are applicable at a higher level. They are proven reusable solutions to common scenarios in software architecture.
Here’s a selection of well-known architectural patterns:
In Multitier architecture, applications are structured in multiple tiers which have separate responsibilities and are usually also physically separated.
Probably the most common application of this architectural pattern is the three-tier architecture that consists of a data access tier (including data storage), a business tier (implementing the business logic) and a presentation tier (i.e. the application user interface).
In Service-Oriented architecture (SOA), application components are implemented as independent standalone services that communicate over a standardized communication protocol.
A standardized service contract describes the functionality exposed by each service. This allows loose coupling between the services and high level of their reusability. When the architecture pattern was first introduced, the most commonly used communication protocol was SOAP.
Microservices are a more modern subset or an evolution of the Service-Oriented architecture (SOA).
As the name implies, they are usually more lightweight, including the communication protocols which are most often REST and gRPC. Each service can use whatever technology works best for it, but they should all be independently deployable with a high level of automation. Microservices and it’s architecture will be covered in the 48th Edition of the DNC Magazine (releasing on October 22nd).
In Event-driven architecture, there’s even more emphasis on loose coupling and asynchronous communication between the components. Although it’s not a requirement, the system can still be distributed, i.e. it can consist of independent services (or microservices).
The main distinguishing factor is that the components don’t communicate with imperative calls. Instead, all the communication takes place using events (or messages) which are posted by components and then listened to by other components that have interest in it.
The component posting the event doesn’t receive any direct response to it. However, it might receive an indirect response by listening to a different message. This makes the communication more asynchronous when compared with the other patterns.
Within a selected high-level architectural pattern, there are still many lower level architectural decisions to be made which specify how an application code will be structured, in even more detail.
There are further patterns available for these decisions, such as the Model-View-Controller (MVC) pattern for web applications and the Model-View-Viewmodel (MVVM) pattern for desktop applications.
As the scope of these patterns becomes even smaller, we sometimes name them design patterns instead of architectural patterns. Examples of those are dependency injection (read more about it in Yacoub Massad’s article Clean Composition Roots with Pure Dependency Injection), singleton (read more about it in my article Singleton in C# – Pattern or Anti-pattern), and others.
After the initial application architecture is defined, it’s necessary to evaluate how it satisfies the list of requirements it’s based on. This is important because in most cases there is no single correct choice for the given requirements.
There are always compromises and every choice has its own set of advantages and disadvantages. A certain architectural choice could, for example, improve the application performance, but also increase operating costs and reduce maintainability. Depending on the relative importance of the affected requirements, such an architectural choice might make sense or not.
Figure 2: Continuous evolution of application architecture
The application architecture is never set in stone.
It needs to evolve as the application is being developed and new knowledge and experience is gathered.
If a certain pattern doesn’t work as expected in the given circumstances, it should be reevaluated and considered for a change. Requirements (functional and non-functional) might change and affect previous architectural decisions as well.
Of course, some architectural patterns are easier to change than others. For example, it’s much easier to introduce dependency injection into an application or change its implementation than to change the application type or core architectural pattern such as MVC.
Official resources for .NET developers
If you’re focusing on the .NET and Azure technology stack, Microsoft offers a lot of official resources to help you get started with architecting applications.
The .NET Architecture Guides website is probably the best starting point. The resources on the site are organized based on the type of application you want to develop. After you select one (e.g. ASP.NET apps or UWP desktop apps), you get a list of free e-books to download that are applicable to the selected application type. The same e-book might be listed under multiple application types if the guidance it contains applies to more than one.
Figure 3: Entry page of the .NET Architecture Guides website
In general, the e-books follow a similar approach and do a good job at introducing the reader to the topic they cover. Typically, they include the following:
- An introduction to the technologies involved.
- An overview of available application sub-types (e.g. MVC vs. single page web applications) and the reasoning behind choosing one.
- A list of common architectural patterns for the application type with explanation.
- A tutorial covering the key parts of an application including sample code.
The books primarily target readers with no prior experience in the subject they cover. Their content is suitable both for software architects and developers. They might still be a valuable read even If you have some prior knowledge. In that case, you might skip some parts of the book or skim over them, but nevertheless you could still pick up a few things or get a more thorough overview of the topic.
Many books are accompanied by working sample applications with full source code available on GitHub. These showcase many of the concepts explained in the books and are regularly updated to the latest versions of technologies they use. Often the samples are also updated with features introduced in new versions of those technologies. It’s a good idea to look at the code before starting a new similar project or implementing a pattern that’s featured in a sample.
Azure Architecture Center is another good resource.
As the name implies, it’s mostly focused on applications being hosted in Microsoft Azure, but many of the patterns are also useful in other scenarios. In my opinion, the most useful part of this site are the Cloud Design Patterns. It consists of a rather large list of architectural patterns, grouped into categories based on their intended use. Similar to how software design patterns are usually documented, each pattern has a description of the problem it addresses and the solution it proposes. Many include sample code and links to related patterns.
While this might not be enough information on its own to fully implement a pattern from scratch, it’s a good basis to compare and evaluate different architectural patterns in the context of your own requirements.
In this article, I explained the concept of application architecture and provided some guidelines on how to approach it. I described the importance of architecture evaluation and evolution. I included links to Microsoft’s official resources about application architecture and suggested how they can be used effectively.
This is the first article in the series about application architecture. In the following articles, I will focus on a selection of architectural patterns for different application types.
Stay tuned for my next article where I talk about Architecture of Desktop and Mobile Applications and Architecture of Web Applications.
This article was technically reviewed by Yacoub Massad.