Software architecture is a Computer Science domain. Usually a software architect is also highly trained and experienced software developer. An architect has a leading role in a software project.
Architects are involved in the initial phase of the project and can move between projects, unlike developers who stick with one single project for a longer time. After an architecture is establish the project no longer require an architect.
Having an architecture design has a positive influence for the quality of software implementation. It can also contribute to cost reduction by elimination of risks for selecting the wrong technology. When the system is well designed then the team members can understand and implement code much faster by looking at the architecture documentation and make parts of the system that match well together, enabling the delivery on time and budget.
Use these bookmarks to read your favorite topic.
When you design an architecture you must consider several aspects.
In the past the focus of designers was to resolve multiple requirements and implement features for the system as fast as possible. This approach can lead to accumulation of technical dept and poor quality. Any project who do not focus on higher quality is doomed to failure.
System attributes
I engineering we have a theory that analyze systems. This theory include concepts and principles that can be extended to software. Next we enumerate some of these concepts:
Quality Attribute | Description |
---|---|
Fault-tolerance | The ability of a system to continue to operate even when some of its components fail. |
Backward compatibility | The ability of a system to continue to work with older versions of itself or with other systems that are not compatible with the latest version. |
Extensibility | The ability of a system to be extended with new features and functionality without affecting the existing functionality. |
Reliability | The ability of a system to work correctly even when there are errors. |
Maintainability | The ability of a system to be maintained and updated without affecting the existing functionality. |
Availability | The ability of a system to be available to users when they need it. |
Efficiency | The ability of a system to use its resources (such as time, memory, and processing power) in an effective and efficient manner. |
Security | The ability of a system to protect its data from unauthorized access, data breaches, and other attacks. |
Usability | The ability of a system to be used by users to achieve their goals effectively and efficiently. |
Portability | The ability of a system to be transferred to a new environment without affecting the existing functionality. |
Your project should address and monitor all these aspects of quality. Identification of quality issues is a profession. There are quality specialists that can perform code review and quality assessment. These persons are very expensive and difficult to have in a company, therefore Software Developers must cover some of these skills.
One of most important concerns of Software Architecture is to establish rules and guidelines for making code of higher quality. After many years of practice we have come to appreciate for some design patterns that can be used to create better code. Next we explain the attributes and considerations for making your code sage.
# | Code attribute | Description |
---|---|---|
1 | comprehensive | readable, consistent, organized |
2 | documented | use comments and annotations |
3 | modular | use separation of concerns |
4 | testable | make small sub-programs and functions | 5 | maintainable | refactoring friendly, easy to debug |
Note: Source code quality do not imply "performance" or "reliability", nor "efficiency" or "business value". Indeed these are also attributes to consider for software quality but they are related to final product not the source code. First think how developers write code and next be concerned about other quality aspects. We believe that code must be beautiful then correct then fast then efficient, in this order.
Most languages are capable of self documented source code, using comments and annotations. It is important to know, some annotations can be parsed by a special program and converted in HTML pages automatically.
In our articles we use examples and comments to explain the essentials. Once you grasp the basics and start codding you will need more. There is nothing better or more complete than a good reference manual. Find it and read it!
We search the internet for add free documentation. Most of the time a computer language has a home page and reference manuals. We use some of these references ourselves when we make tutorial articles.
When you design an application or a system you should describe some of your design principles and make them public. If you do not have time to make your own principles use next generic principles instead:
Modular: a system is an aggregation of multiple sub-systems. The sub-systems collaborate and communicate using messages and rules. If your system is monolithic it will be harder to build, test and maintain. Apply KISS principles (Keep it Simple Stupid). This means just design the features that you need. Architectures that are more complex than necessary will result in sub-optimal systems. Breaking this rule is called over-engineering. This should be avoided.
Holistic: A good system must define terminology and principles for definition of components and relations between them. A metaphor could help for building a theory using existing therms and analogy from real life.
Brilliance: A system architecture must be conceptual elegant, but architects should not be blinded by the beauty of creation, and always review features with a pragmatic and detail-oriented eye.
Next table show you advices that can be an example of principles an architect should enumerate in architecural runway principles. These are Sage-Code advices, you can modify and add new advices for your own organization.
Advice | Comments |
---|---|
Never release or deploy untested software. | This is one of the most important rules in software engineering. It is essential to test your software thoroughly before releasing it to the public. |
Store testing code and application code together. | This will make it easier to maintain and update your tests. |
Save and version control your configuration files. | This will help you to track changes to your configuration files and to restore them if necessary. |
Start your source files with a short comment. | This will help you to understand the purpose of the file and to document your code. |
Do not stay astray from left side of the screen. | This will help to make your code more readable and easier to maintain. |
Short lines of code are better than long lines. | This will make your code easier to read and understand. |
Group global variables and constants in records or structures. | This will make your code more organized and easier to understand. |
Create a local scope if possible. Local is better then the global. | This will help to prevent name collisions and to make your code more readable. |
It is better to define global constants than to use magic literals. | This will make your code more readable and easier to understand. |
Use comments in your code and make references to documentation. | This will help to document your code and to make it easier to understand. |
Create subroutines only if you need to. Subroutine call can be expensive. | This will help to improve the performance of your code. |
Avoid unnecessary data movement by using references. | This will help to improve the performance of your code. |
Favor explicit declarations against type inference or gradual types. | This will help to make your code more readable and easier to understand. |
Favor explicit loop and stacks over recursive functions. | This will help to improve the performance of your code and to make it easier to understand. |
Favor different identifiers over subroutine overloading. | This will help to make your code more readable and easier to understand. |
Do not be afraid of long identifier names for subroutines and variables. | This will help to make your code more readable and easier to understand. |
Do not be afraid of long processes: create subroutines only when necessary. | This will help to improve the performance of your code. |
Do not be afraid to do refectory whenever you think is necessary. | This will help to improve the quality of your code. |
Do not create functionality that is not required: let the future to care about itself. | This will help to keep your code lean and easy to maintain. |
Favor declarative programming over imperative programming. | This will help to make your code more readable and easier to understand. |
Favor imperative programming over functional programming. | This will help to make your code more efficient. |
Favor functional programming over object oriented programming. | This will help to make your code more modular and easier to test. |
Avoid deep class trees. They are hard to understand and debug. | This will help to make your code more readable and easier to maintain. |
Avoid classes with features and favor mix-in classes or traits instead. | This will help to make your code more modular and easier to test. |
Favor precondition checking over exception handling. | This will help to improve the performance of your code. |
Favor efficient algorithms over parallel computing. | This will help to improve the performance of your code. |
These are just a few of the many good practices that can help you to write better software. By following these practices, you can improve the quality, performance, and maintainability of your code.
The name of identifiers in a language can support several characters. In most languages identifier name usually starts with lowercase letters (a..z) or capital letters (A..Z) followed by one or more characters or numbers. No special characters or spaces are permitted in the name except underscore ("_").
A variable name can start or terminate with underscore or can contain underscores. The underscore is equivalent to space. So the identifiers that have space in a JSON or in a database can be mapped to internal variables that use an underscore instead of a space as identifier.
Examples: These are invalid identifiers:
Examples: These are valid identifiers:
Variables usually have a meaning or a purpose therefore variable must have a proper name. Variables can’t use as names the language reserved keywords. Therefore we advise for variables to use a prefix all the time.
"v_" is a good prefix for variables; "p_" is a good prefix for parameters;
Using prefix is good but sometimes this is not good enough. When this is the case, you can give creative names to variables to make your code even more readable.
Example: In next Python example we name a logical variable: URGENT and use "==" operator. By not using a prefix for logical variable we make a very readable program.
# python code
URGENT = True
if situation == URGENT:
print("this is an emergency")
else:
print("this is a normal situation")
pass # end if
Your convention: You may setup your own naming conventions. Just make sure all developers in your team follow the same convention. Otherwise some developers will use one style while others will try to use something different and your conceptual brilliance will be shadowed by a messy implementation.
Avoid it! It can cause a disaster when your code is versioned. Automatic formatting is available for some languages and is a program that modify your source code to look nice. I strongly advice against it. You can be fired if you do not listen this advice.
Doing automating formatting for totally new code can be beneficial for learning how your code should look like. You can apply automatic formatting in early stage of a new file but never to an older file. Later code review will be impossible. I advice you to do only manual code re-formatting.
A design pattern is a general, reusable solution to a commonly occurring problem in software architecture within a given context. There are many recognized architectural patterns and styles. We will elaborate this topic in next article.
In many software systems we use a database on a server to organize large amount of data. When we use a database server the application is centralized. A database can be used in many different architecture patterns:
In picture below we can see the general idea of a client-server architecture. All clients are connected to a central server that store the database. The client send messages to the server and receive information. This way all the clients can communicate to the server but they can't communicate to each-other.
Distributed Architecture
In this architecture there are several clients connected in a local network. The clients are connector through a "router". The router is connected to an "application server" that is also connected to a database server. Of course, other local networks can be connected to the same "data center".
Multi Tier Architecture
A peer-to-peer (P2P) architecture consists of a decentralized network of peers - nodes that are both clients and servers. P2P networks distribute the workload between peers, and all peers contribute and consume resources within the network without the need for a centralized server.
P2P Architecture
A service in general is a kind of application that do not have user interface of it's own. This application start automatic when the server start and resides in memory until the server is shut-down. A web service is a small program that is run by a application server. A web service can create JSON response stream or file on request. The application server can send this response to client using http protocol.
The dynamic web page is a special HTML page that is loaded in the web browser and has JavaScript code inside. So the web browser now is smart and has a user interface ready for interaction. Inside the HTML we have AJAX application based on JavaScript. This can send request and receive response from a Web Service. The client application will use JavaScript to parse JSON data and modify the page content.
This is general concept of a cloud based architecture. The server is somewhere on the internet and can be one or more servers. Clients are devices and computers distributed over the world.
Cloud Architecture
Serverless computing (or serverless for short), is an execution model where the cloud provider (AWS, Azure, or Google Cloud) is responsible for executing a piece of code by dynamically allocating the resources.
Serverless is sometimes referred to as “Functions as a Service” or “FaaS”. Following are the FaaS offerings of the major cloud providers:
Serverless architecture is very different from P2P. It does involve servers, except these servers are not dedicated to your application. Servers are shared between many applications. You pay only for the resources used and not for renting and locking resources for a period of time..
Serverless technology is based on stateless functions that run inside a container. This need a "warm-up" time you have to consider when you call a function. The duration of cold start depends on the runtime (language) and the function size. The architecture of serverless applications must consider these challenges.
To build a website you can use HTML/CSS and JavaScript. HTML/CSS are not Turing complete programming languages. You can do static pages using only HTML. Fortunately the web browsers are programmable platforms. You can interact with these programs using JavaScript.
Your career will greatly benefit from making a website. You should follow these basic principles:
In this order, but number 4 should be considered from start. Complexity can kill a project sooner or later. Making a site work is not so simple and is the first step because you must start with a prototype and then improve.
To do the front-end you need HTML+CSS & JavaScript. If you learn these languages you can make websites but also desktop applications. HTML+CSS are two languages actually. But you learn them together. Some people argue that these are not languages but do not listen to them. These both are programming languages, more precise: data oriented language.
JavaScript is very specific to web programming. It can be used for making a dynamic website. Usually belong to front-end design but can be used also for back-end programming. It has a very small runtime and it can be executed into a browser.
You can write back-end programs using any of the following languages: Python, Java, Julia, Go, Ruby … In general each language has it's own back-end framework. Though when you use a framework it become fuse what part is the front end (View/Model) and what part is the back-end (Model/Controller)
JavaScript has evolved and now you can do the back-end using JavaScript. Using same language for both back-end and front-end can be appealing. This will give you productivity.
For JavaScript back-end you need to use a Node.JS engine and a Web Framework. This framework can be one of: {Ember, Angular, React or Vue}. I think the best framework right now is Vue. React is now more popular and used by companies. Angular people say is overengineered and will be abandoned by Google sooner or later.
Select one of the languages: {Python, Ruby, Julia, Go, Rust, C++, Java, Scala}. These are used for server-side/(back-end) and system programming. These languages are preferred by back-end developers. If you learn at least one language in this category you can perform professional development tasks in a company. You should apply for a job or continue your freelancing activity on next level.
SOLID is a set of five principles for object-oriented design (OOD) that are intended to make software more understandable, flexible, and maintainable. The principles are:
SOLID principles can be applied to any programming language, but they are particularly relevant to web development because web applications are often complex and require a lot of code. By following SOLID principles, developers can create web applications that are easier to understand, maintain, and extend.
Here are some examples of how SOLID principles can be applied to web development:
By following SOLID principles, developers can create web applications that are easier to understand, maintain, and extend. This can lead to shorter development cycles, fewer bugs, and happier users.
Here's some things you must do to set-up a project. At the beginning you may be working alone but you will probably add some more people in a few months and it's not going so smoothly if you do not set-up the project properly. Let's say you currently work at a company on some big Web development , software & programming projects. You do everything by yourself from back-end to front-end. What is wrong with this?
It is not very good to do all by yourself. In computer programming we work in a team. Somebody is doing something and someone else is doing something different. The collaboration is helping team members to learn from each other. This is how we can build larger projects.
The 10 steps to create a project
Hosting: After you create a web-site on your computer, you have to deploy it to a web host server to be visible over the internet. Hosting a website is not easy. You need a domain name, and this cost's you money. Then you need to know how to connect to the server and upload files.
For more advanced topics you should follow my blog. I post frequently and you can find valuable resources. I explain fundamental concepts and mention use cases of different technologies. You can create software only if you understand the components you can use to establish a good architecture for your project.
I hope you enjoy this reading. Good luck!
Read next: Design Patterns