Software architecture 101 - introduction to the world of application design

Application Design Proccess.

Hello, everyone!

Today, I would like to introduce you to the world of application design.

Designing applications can be called a multidisciplinary task, and it includes:

  • a study of design patterns
  • a study of rules for describing architectural schemes
  • knowledge of algorithms and data structures
  • knowledge of distributed computing principles

Why should we build an application architecture?

I want to consider the question — Why should we build an application architecture? I will ask 4 additional questions, which will hopefully answer the main one:

  • What main components (modules) can an application be divided into?
  • How to share responsibility between components?
  • How to prepare the application for future changes?
  • How much will it cost to develop?

What main components (modules) can an application be divided into?

The question “Why divide” arises? It will allow us to:

  • Reduce the interdependence of parts of the code
  • Provide code testability, especially in case of unit tests
  • Clearly delineate the responsibilities of each component
  • Identify frequently used components and make them common (using polymorphism, in particular)
  • Determine which pattern (abstraction) to apply to an application

Once we set goals for the application architecture, we can start preparing Sequence Diagrams. Sequence Diagrams are great for translating business requirements into a distinct set of operations between various application components. Also, given Sequence Diagrams of the app, we could refactor architecture & planned functionality to reduce complexity & increase the app's effectiveness even before writing a single line of code!

Initial Sequence Diagram.

Initial Sequence Diagram

Sequence Diagram after Refactoring.

Sequence Diagram after refactoring

Components Diagram.

Components Diagram

After defining the application's tasks and functions, we turn to a Component Diagram with a description of the components themselves and their relationships.

How to share responsibility between components?

I mentioned polymorphism and design patterns. And on these topics, I would like to elaborate because entering abstractions into the code allows distinguishing components and their roles in the application more clearly.

Among the design patterns, I would like to highlight the following:

  • Facade
  • Strategy
  • Inversion of Control — which is actually an architectural principle

Facade

It is a structural design pattern that provides a simple interface to a complex system of components (classes, libraries, etc.)

Simple Interface to a Complex System of Components.

Strategy

Behavioral Design Pattern.

This behavioral design pattern defines a family of similar algorithms and places each of them in its own class, after which the algorithms can be interchanged right at runtime.

Inversion of Control

Inversion of Control.

This is an architectural principle where the framework controls the program control flow, and the custom code is embedded at specific execution points. ReactJS is a good example of IoC principle usage. Much of the application logic is implemented and controlled by the framework itself, so the software developer's sole responsibility is to alter the framework’s behavior at provided points (useState, useEffect, etc.)

How to prepare the application for future changes?

With the architectural schemes and TOR in place, you can already begin to plan tasks for implementation and provide for future changes. Here, I used the word “provide” intentionally. Of course, architects are not visionaries, but as they get more experience, they learn to see and predict the vector of the application. In practice, few tasks require a fundamental redevelopment of the application or the business model — unless, of course, we are talking about an MVP or some unique features that need to be implemented.

Also, by applying a certain abstraction, we already have predictable tools to implement most ideas, and this allows us to keep time-to-market on a certain level.

How much will it cost to develop?

And this is one of the key questions that the architect and architectural schemes are trying to answer. The cost of software development itself depends on many factors, but the main one is the programmer’s time needed to write a working application with which the end-user can already interact. The architect's task is to define — together with the business and project managers — a minimum sufficient set of functions for each stage of project development. The next task is to proceed to develop the schemes of each of the parts (modules) without losing focus on the entire application as a whole and the features implemented in the late stages of development. It is possible because you can create a super tricked-out application on paper but fail to implement it within a reasonable timeframe.

Image.

Who should do it?

All this time, I’ve been mentioning the architect, and you may have the question — Who is the architect? In my understanding, an architect is a person with a lot of development experience at different levels and with analytical skills. And no matter how controversial it sounds, every member of the team can be an architect at different stages of making architectural diagrams.

Flow Diagrams Which Reflect a Specific Implementation of Application Logic.

For example, flow diagrams should reflect a specific implementation of logic, but if you have a multi-component application, preparing only flow diagrams for the whole logic can take an indecent amount of time. So it is important to delegate this work to the developers of this very logic. It will allow both parallelizing the work and identifying the pitfalls. After all, the developers have expertise in their subject areas and can identify controversial points in the whole architecture.

However, when delegating authority, it is important to give one person or group of people the right to make or reject changes in architecture because only architects have the fullness of the picture.

To summarize, maintaining architecture is a team effort, and the more involved the developers are, the more predictable the development itself becomes.

Does everything end after drawing?

Of course not! Development requires creativity at every moment, and it is not uncommon to have to change the plan and the code on the fly. Still, at this point, it is crucial to calculate the change in the architectural plans and, if all is well, start the development.

The architecture of the application is a living organism, and we should support it all the time.

Therefore, the architectural plans are developing all the time as the application itself is developing.

That’s all I have. Thank you for your attention.

Nuradil Alymkulov.

Nuradil Alymkulov

Full Stack Developer
Custom Software and Mobile App Development.
Golang.

Underestimating Go

Underestimating Go

Underestimating Go

Hi, I’m Pavel!I’m a software engineer in Mad Devs. In the past six years, I’ve been working with Ruby and Rails, also I love React and Redux. I was a...

Best architecture for the React Project.

Best architecture for the React Project

Best architecture for the React...

Best architecture for the React Project

Usually, at the preparatory stages of project developers think of the project skeleton to avoid a lot of mistakes and reworks in the future.What is...