Design Patterns in C++
A design pattern offers an all-encompassing, repeatable answer to the typical issues that arise in software design. Usually, the pattern demonstrates the connections and interactions between several classes or objects. By offering tried-and-true development/design models, the goal is to hasten the development cycle.
It's not necessary to apply design patterns to every aspect of your project. Project development is not the intended use of design patterns. Design patterns are used to help with everyday problems. To stop such problems in the coming time, one must always develop a proper pattern whenever a requirement arises.
Objective
Knowing the functions and applications of each design pattern can help you choose and employ it as appropriate in a given context.
Example
Creating just one example of a class is what we want to accomplish in several real-world scenarios. For instance, a country may only have one functioning president at any particular time. A Singleton pattern is what we're talking about here.
As it is expensive to create a distinct DB connection for each object, other software instances might have a single DB connection utilized by several objects. Similarly, to this, an application can have a single configuration manager or error controller that takes care of all issues rather than having several managers.
Types of Design Patterns
Design patterns typically fall into one of three categories:
1. Creational
Class initialization or object generation is the central theme of these design patterns. Such patterns may also be divided into patterns for creating classes and patterns for creating objects. Whereas class-creation patterns successfully employ inheritance throughout the initialization process, object-creation patterns successfully use delegation.
The Factory Method, Abstract Factory, Builder, Singleton, Object Pool, and Prototype are examples of creational design concepts.
Factory Methods
Intent:
A creational design pattern called the factory method gives subclasses the ability to change the object types that will be generated while still providing an interface for producing objects in a superclass.

Problem:
Create a logistics operations app, for example. The majority of your code is located inside the Truck class since the initial version of your software can only handle truck transportation.
Your app starts to get a lot of traction eventually. You get hundreds of inquiries from shipping firms each day asking you to include marine logistics in the app.
Wonderful news, yes? How about the coding, though? The majority of your code is now tied to the Truck class. The entire software would need to be modified in order to integrate Ships into the app. Additionally; you will likely need to implement all of these adjustments once more if you decide to subsequently include another mode of transportation in the application.
As an outcome, your code will be rather bad, full of conditionals that change how the program behaves according to the kind of transportation elements.
Solution:
The factory design pattern advises switching out calls to the new unit for direct object formation calls with calls to a unique factory method. Not to worry, the new mode is still used to construct the objects, but it is now called inside the factory function. Products are frequently used to describe objects that a factory operation returns.

This modification may appear unnecessary at first glance because we just shifted the function Object() { [native code] } call from one area of the program to another. But take into account that you may now alter the class of goods that the factory function creates by overriding it in a subclass.
However, there is a little restriction: subclasses can only return several product types if they share a base class or interface. Additionally, the base class' factory method's returned type must be specified to be this interface.

For instance, the Transport method, which has the deliver function, should be implemented by both the Truck and Ship classes. This strategy is applied separately by each class: ships convey freight by water, whereas trucks distribute cargo by land. Truck objects are returned by the factory method in the RoadLogistics class, while ships are returned by the factory method in the SeaLogistics class.
The actual goods produced by different subclasses are identical to the code that utilizes the factory function (commonly referred to as the client code). The customer views every product as an abstract Transport. Although the client is aware that the delivery method should be included in all transport objects, the specifics of how it operates are unimportant to the client.
Use case of creational design pattern
- Assume that a developer wishes to design a straightforward DBConnection class to attach to a database and access this information from code in numerous places. Typically, the developer will construct an instance of the DBConnection class and utilize it to perform logic operations as necessary. As a result, several linkages to the database are created as each example of the DBConnection class has its own connection to the database. To address it, we develop the DBConnection class as a singleton class, resulting in the creation of just one example of DBConnection and the establishment of a single connection. We can handle load balancing, unused connections, etc. since we can handle DB Connection through a single instance.
- If you wish to establish loose coupling and several examples of the same sort, you may use the factory approach. A class that uses the factory design pattern functions as a link between other classes. Take many database servers like SQL Server and Oracle as an instance. Factory design structures manage loose coupling and simple execution; therefore we should choose them in order to obtain loose coupling and the formation of a similar type of object. For example, if you are creating an app using a SQL Server database as the back end and yet later need to switch to an Oracle database, you will be required to adjust all your code.
And you can explore another design model of creational design pattern, which is mentioned above.
2. Structural
These design patterns focus on grouping several classes and objects into more substantial structures that offer fresh functionality. Following are some examples of this type of design.
Adapter, Bridge, Composite, Decorators, etc are examples of structural design patterns.
Adapter:
Intent:
A structural design pattern called an adapter enables items with disparate APIs to work together.
Problem:
Consider developing a stock market tracking app. The program receives the stock data in XML format from several places and then shows the user appealing charts and diagrams.
You eventually make the decision to enhance the app by using a clever third-party analytics package. The analytics library only functions with data in JSON format, thus there is a catch.
The library could be modified to support XML. Furthermore, certain existing code that depends on the library can be broken as a result. And to make matters worse, you could not even have had access to the library's source code, rendering this strategy useless.
Use Case of Structural Design Pattern
An adapter design pattern is used when two interfaces that are incompatible with one another attempt to form a relationship using an adapter. The adapter pattern transforms a class's interface into a different interface or class that the customer requires, allowing classes that would not have been able to coexist due to incompatibility to do so. We may use the adapter approach in these kinds of incompatible cases.
Composite:
Intent:
With the use of the structural design pattern known as Composite, you may group things into diagrams and then treat those structures as specific items.

Problem:
Only when your app's main design can be shown as a tree does use the Composite design make sense.
Consider having two different kinds of items, such as boxes and products. A Box may include a variety of products as well as many smaller Boxes. These tiny boxes may also accommodate other products or even more diminutive boxes, and so on.
Let's say you choose to use these classes to develop an ordering system. Orders may include plain goods that are not packaged, as well as boxes that are packed with goods and additional boxes. How would you calculate the order's total cost?

Various goods may be included in an order, each wrapped in a box, which is then placed in a larger box, and so on. The entire building has the appearance of an upside-down tree.
You could go the straightforward route and open every package, inspect every item, and then add it all up. In the actual world, that might be possible, but in a program, it wouldn't be as straightforward as executing a loop. You must be aware of the categories of goods and boxes you'll be dealing with, the boxes' level of stacking, and other unpleasant information, in advance. The straightforward method is either too difficult or possibly impossible because of all of this.
And you can explore another design model of structural design pattern, which is mentioned above.
3. Behavioural
The goal of behavioural patterns is to identify the previous communication styles across things.
The Chain of Responsibility pattern, Command, Interpreter, Iterator, Mediator, Memento, Null Object, etc are examples of behavioural patterns.
Chain of Responsibility:
Intent:
You may transmit queries down a chain of handlers using the behavioral design pattern known as the Chain of Responsibility. Every handler chooses whether to execute a request or send it to the handler behind it in the chain.

Problem:
Consider you are developing an internet ordering system. You need to limit access to the system so that only users who have been verified may make orders. Additionally, individuals with admin rights must have complete access to all transactions.
After some preparation, you understood that these tests needed to be carried out in order. Anytime the program gets a request with the user's credentials, it may try to verify the user with the system. There is no need to carry out any more tests if verification fails because those credentials were incorrect.

Well before the order management system alone can process the request, a number of checks must be passed.
You put in place numerous more such consecutive inspections over the next couple of months.
- One of your coworkers said it was risky to send raw data directly to the ordering system. So, to sanitize the data in a query, you introduced an additional validation step.
- Someone later discovered that the system is susceptible to password brute-force attacks. You quickly included a check that filters out repeated unsuccessful requests originating from the same IP address to counteract this.
- Another person proposed that you might speed up the system by responding to repeated queries for the same data with cached results. As a result, you introduced an additional check that only permits the request to reach the system if no appropriate cached answer exists.

The code for the inspections, which already seemed to be a jumble, became larger and larger since each new product was introduced. Sometimes altering one test has an impact on the others. Most troubling of all, developers had to repeat some code while attempting to reuse the procedures to safeguard another entire system since parts of the tests were needed but not every one of them.
The system grew to be exceedingly complex and costly to maintain. You spent some time struggling with the code before deciding to rework it all at once.
Solution:
The Chain of Responsibility, like numerous other behavioral design patterns, depends on turning specific activities into independent usually called handlers. In this situation, every test should be separated into its own class and handled by a single function. This procedure receives the request as well as its data as a parameter.
The pattern advises creating a chain out of these handlers. A field on every connected handler may be used to store a reference to the handler after it in the network. Handlers transmit requests farther up the chain in addition to dealing with them. Until each handler has had an opportunity to handle the request, it moves up the chain.
The finest element is that a handler has the option to determine whether to stop processing a request and transmit it no farther in the chain.
In our illustration of ordering systems, a handler processes the request and then chooses whether to send it to a subsequent link in the chain. Every handler, whether doing verification tests or caching, may carry out their main activity if the request provides the appropriate data.

A handler chooses whether it is able to process a query after getting it, which is a little different method that is a little more standard. If it can, it declines to transmit the request. Therefore, either one controller or no handlers at all execute the request. While handling actions in stacks of items inside a graphical user interface(GUI), this strategy is quite popular.
Behavioural Design Pattern Use Case:
The template pattern outlines an algorithm's basic stages while delegating others to subclasses. The template technique enables subclasses to rewrite specific algorithmic stages without altering the framework of the algorithm. For instance, in your development, you would want the capsule's behaviour to be extendable so that it may act in new and novel ways when the application's specifications evolve or to accommodate the demands of brand-new applications. Nobody is permitted to alter the source code, therefore in those situations when a developer may use the template design pattern, someone can add things but not change the layout.
And you can explore another design model of behaviouraldesign pattern, which is mentioned above.