Software Architecture | Architectural patterns | Architecture vs. Design pattern

This post is part of The Software Architecture Chronicles, a series of posts about Software Architecture. In them, I write about what I’ve learned on Software Architecture, how I think of it, and how I use that knowledge. The contents of this post might make more sense if you read the previous posts in this series.

In the last post, I wrote about how programming languages have evolved and what it tells us: that they evolved always in the direction of providing for more modularity and encapsulation.

In the following posts, I will write about Architectural Styles and Architectural Patterns evolution, so today I will write about what is an Architectural Style and what is an Architectural Pattern.

As much terminology in Software Development, these terms are not clear and different people give it a different meaning. MSDN says that Architectural Styles and Architectural Patterns are the same things, but personally, I prefer to think of these in the lines of what is explained by George Fairbanks and Michael Keeling, what is said in this stack overflow answers and how Wikipedia separates the two: the key difference is the scope.

It is also important to reinforce the idea that Architectural Styles, Architectural Patterns and Design Patterns are not mutually exclusive, they are complementary and they all can teach us something, although, as usual, they should be used only when needed.

Architectural Styles

Architectural styles tell us, in very broad strokes, how to organise our code. It’s the highest level of granularity and it specifies layers, high-level modules of the application and how those modules and layers interact with each other, the relations between them. Examples of Architectural Styles:

  • Component-based
  • Monolithic application
  • Layered
  • Pipes and filters
  • Event-driven
  • Publish-subscribe
  • Plug-ins
  • Client-server
  • Service-oriented

Advertisements

about:blank

REPORT THIS AD

An Architectural Style can be implemented in various ways, with a specific technical environment, specific policies, frameworks or practices.

Architectural Patterns

A pattern is a recurring solution to a recurring problem. In the case of Architectural Patterns, they solve the problems related to the Architectural Style. For example, “what classes will we have and how will they interact, in order to implement a system with a specific set of layers, or “what high-level modules will have in our Service-Oriented Architecture and how will they communicate“, or how many tiers will our Client-server Architecture have“.

Architectural Patterns have an extensive impact on the code base, most often impacting the whole application either horizontally (ie. how to structure the code inside a layer) or vertically (ie. how a request is processed from the outer layers into the inner layers and back). Examples of Architectural Patterns:

  • Three-tier
  • Microkernel
  • Model-View-Controller
  • Model-View-ViewModel

Design Patterns

Design Patterns differ from Architectural Patterns in their scope, they are more localised, they have less impact on the code base, they impact a specific section of the code base, for example:

  • How to instantiate an object when we only know what type needs to be instantiated at run time (maybe a Factory Class?);
  • How to make an object behave differently according to its state (maybe a state machine, or a Strategy Pattern?).

Conclusion

As I mentioned in the beginning of this post, it’s all about the scope:

  • An Architectural Style is the application design at the highest level of abstraction;
  • An Architectural Pattern is a way to implement an Architectural Style;
  • A Design Pattern is a way to solve a localised problem.

Furthermore, a pattern might be able to be used both as an Architectural Pattern or a Design Pattern, again depending on the scope we use it in, in a specific project.

Design Patterns

What’s a design pattern?

Design patterns are typical solutions to commonly occurring problems in software design. They are like pre-made blueprints that you can customize to solve a recurring design problem in your code.

You can’t just find a pattern and copy it into your program, the way you can with off-the-shelf functions or libraries. The pattern is not a specific piece of code, but a general concept for solving a particular problem. You can follow the pattern details and implement a solution that suits the realities of your own program.

Patterns are often confused with algorithms, because both concepts describe typical solutions to some known problems. While an algorithm always defines a clear set of actions that can achieve some goal, a pattern is a more high-level description of a solution. The code of the same pattern applied to two different programs may be different.

An analogy to an algorithm is a cooking recipe: both have clear steps to achieve a goal. On the other hand, a pattern is more like a blueprint: you can see what the result and its features are, but the exact order of implementation is up to you.

What does the pattern consist of?

Most patterns are described very formally so people can reproduce them in many contexts. Here are the sections that are usually present in a pattern description:

  • Intent of the pattern briefly describes both the problem and the solution.
  • Motivation further explains the problem and the solution the pattern makes possible.
  • Structure of classes shows each part of the pattern and how they are related.
  • Code example in one of the popular programming languages makes it easier to grasp the idea behind the pattern.

Some pattern catalogs list other useful details, such as applicability of the pattern, implementation steps and relations with other patterns.

History of patterns

Who invented patterns? That’s a good, but not a very accurate, question. Design patterns aren’t obscure, sophisticated concepts—quite the opposite. Patterns are typical solutions to common problems in object-oriented design. When a solution gets repeated over and over in various projects, someone eventually puts a name to it and describes the solution in detail. That’s basically how a pattern gets discovered.

The concept of patterns was first described by Christopher Alexander in A Pattern Language: Towns, Buildings, Construction. The book describes a “language” for designing the urban environment. The units of this language are patterns. They may describe how high windows should be, how many levels a building should have, how large green areas in a neighborhood are supposed to be, and so on.

The idea was picked up by four authors: Erich Gamma, John Vlissides, Ralph Johnson, and Richard Helm. In 1994, they published Design Patterns: Elements of Reusable Object-Oriented Software, in which they applied the concept of design patterns to programming. The book featured 23 patterns solving various problems of object-oriented design and became a best-seller very quickly. Due to its lengthy name, people started to call it “the book by the gang of four” which was soon shortened to simply “the GoF book”.

Since then, dozens of other object-oriented patterns have been discovered. The “pattern approach” became very popular in other programming fields, so lots of other patterns now exist outside of object-oriented design as well.

Why should I learn patterns?

The truth is that you might manage to work as a programmer for many years without knowing about a single pattern. A lot of people do just that. Even in that case, though, you might be implementing some patterns without even knowing it. So why would you spend time learning them?

  • Design patterns are a toolkit of tried and tested solutions to common problems in software design. Even if you never encounter these problems, knowing patterns is still useful because it teaches you how to solve all sorts of problems using principles of object-oriented design.
  • Design patterns define a common language that you and your teammates can use to communicate more efficiently. You can say, “Oh, just use a Singleton for that,” and everyone will understand the idea behind your suggestion. No need to explain what a singleton is if you know the pattern and its name.

Criticism of patterns

It seems like only lazy people haven’t criticized design patterns yet. Let’s take a look at the most typical arguments against using patterns.

Kludges for a weak programming language 

Usually the need for patterns arises when people choose a programming language or a technology that lacks the necessary level of abstraction. In this case, patterns become a kludge that gives the language much-needed super-abilities.

For example, the Strategy pattern can be implemented with a simple anonymous (lambda) function in most modern programming languages.

Inefficient solutions

Patterns try to systematize approaches that are already widely used. This unification is viewed by many as a dogma, and they implement patterns “to the letter”, without adapting them to the context of their project.

Unjustified use

If all you have is a hammer, everything looks like a nail.

This is the problem that haunts many novices who have just familiarized themselves with patterns. Having learned about patterns, they try to apply them everywhere, even in situations where simpler code would do just fine.

Classification of patterns

Design patterns differ by their complexity, level of detail and scale of applicability to the entire system being designed. I like the analogy to road construction: you can make an intersection safer by either installing some traffic lights or building an entire multi-level interchange with underground passages for pedestrians.

The most basic and low-level patterns are often called idioms. They usually apply only to a single programming language.

The most universal and high-level patterns are architectural patterns. Developers can implement these patterns in virtually any language. Unlike other patterns, they can be used to design the architecture of an entire application.

In addition, all patterns can be categorized by their intent, or purpose. This book covers three main groups of patterns:

  • Creational patterns provide object creation mechanisms that increase flexibility and reuse of existing code.
  • Structural patterns explain how to assemble objects and classes into larger structures, while keeping these structures flexible and efficient.
  • Behavioral patterns take care of effective communication and the assignment of responsibilities between objects.

The Catalog of Design Patterns

Creational patterns

These patterns provide various object creation mechanisms, which increase flexibility and reuse of existing code.

Factory MethodAbstract FactoryBuilderPrototypeSingleton

Structural patterns

These patterns explain how to assemble objects and classes into larger structures while keeping these structures flexible and efficient.

AdapterBridgeCompositeDecoratorFacadeFlyweightProxy

Behavioral patterns

These patterns are concerned with algorithms and the assignment of responsibilities between objects.

What’s New in .NET 7

Introduction

We are all excited about the release of .NET 7, and as we know, every year around November, Microsoft releases the latest version of .NET. The last version, .NET 6, was released on November 8, 2021, and following the same timeline, Microsoft made the .NET 7 release date on November 8, 2022, the opening day of the three-day .NET Conf online event which is the same as the previous year’s launch date .NET 6. The great news in this year’s new version is that it focuses primarily on being unified, modern, simple, and fast. So, without much ado, let us jump to the specifics.

What’s New in .NET 7 Features and Updates

Microsoft has introduced .NET version 7 with an STS (standard-term support) or the shorter supported version providing only 18 months of support. Microsoft introduced the STS version this year because it already mentioned in 2019 that it would release a new version of .NET every year around November. But, considering the new official .NET 7 features and updates, it still brings a significant number of changes and .NET 7 performance improvements for the Users. Given below are 17 noteworthy differences between .NET 7 vs .NET 6 are as follows:

1. On-stack replacement (OSR) that allows changing the executed code by a way in the middle of its execution. This will help the long-running methods to shift to a faster version in the middle of the execution.

2. Regex Improvements: Some regular expression improvements which make them a bit better in .NET 7.

3. Simplified LINQ Ordering

4. Dynamic PGO Improvements: The Dynamic PGO, is designed to make some key changes from the Static PGO which requires developers to use special tools separately from training, Dynamic PGO doesn’t require any of that; all you need to do is run the application you are interested in optimizing and then collect data for Microsoft!

5. Reflection Improvements: With this update by Microsoft, now in .NET 7 the overhead when invoking a member using reflection has been reduced considerably.

6. Application Trimming Improvements: Trim stuff that you don’t need in your specific application and make a smaller application thereby giving a smaller .exe size.

7. Trimming Libraries: Trim libraries that you don’t need or are not necessary for you.

8. Nanoseconds and Microseconds values in Date Time allow you more specific values from the Date Time object.

9. Memory Caching Improvements which is specifically in ASP.NET but this is an improvement in How we do memory caching.

10. TAR File Creation: .NET 6 already allowed .ZIP file creation but the latest version .NET 7 now allows creating .TAR file.

11. Blazor Changes: Blank Templates, Sample Blazor Template (with no sample data started in it),