×

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.

Design Patterns in C++

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.

Design Patterns in C++

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.

Design Patterns in C++

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

  1. 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.
  2. 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.

Design Patterns in C++

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?

Design Patterns in C++

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.

Design Patterns in C++

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.

Design Patterns in C++

 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.
Design Patterns in C++

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.

Design Patterns in C++

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.


Related Topics

C++ Multimap

Definition: In C++, a multimap is similar to a map with the additional concept, where multiple elements possess the same keys. It is also not necessary that the key values and...

4 minutes read.

Lexicographically Next Permutation in C++

In this tutorial, we'll look at how to use C++ to generate the lexicographically next permutation of a string. The lexicographically next permutation is the larger permutation. "ACB," for example,...

3 minutes read.

Continue in C++ While loop

Continue statement: Inside the loop, the continue statement is used to control the loop. C++ utilizes the continue keyword to implement the continue statement, which transfers the program's flow at the...

4 minutes read.

Program to find the GCD of two numbers in C++

Before understanding the program of GCD or HCF, one must know what GCD or HCF is. What is GCD? The GCD is referred to as Greatest Common Divisor. HCF is the other...

8 minutes read.

Single dimension array

C++ Array An array is a collection of data (elements) of the same data types. The elements of an array are allocated in contiguous memory allocation. Elements of the array are accessed through...

1 minute read.

C++ Range-based For Loop

In C++ language, the range-based for loop was added, which is far superior than the ordinary For loop. The implementation of a range-based for loop doesn't really need much code. It's a...

4 minutes read.

C++ Virtual Destructor

In C++, a destructor is a class member function that is used to free up space or remove an object of the class that has gone out of scope. The...

4 minutes read.

C++ Void Pointer

A void pointer is a general purpose pointer that can have an address of any data type but is not related to any data type. Void Pointer Syntax: void *ptr;  We can't...

2 minutes read.

Call by Pointer in C++

What is Pointer? Every variable in C++ has a specific address or location in the computer's memory, and this address is known as the memory address. A pointer can be defined...

5 minutes read.

Include Guards in C++

In C++ programming, we frequently utilize a class more than once, so it is necessary to create a header file and include it in the main program. Now, occasionally a...

3 minutes read.

Desired Capabilities in Selenium Web Driver in C++

A class called Desired Capabilities is used to specify a set of fundamental requirements, such as browser, operating system, and version combinations.to carry out automated testing of a web application...

7 minutes read.

C++ int into String

Data type conversion is a standard editing process. You may need to convert variable from one type of data to another in a variety of situations. There are two ways...

5 minutes read.

C++ Friend Functions

In C++, friends are special functions that are not a part of a class yet have access to its private and protected members. The friend keyword is used to declare...

4 minutes read.

C++ Deque

Definition: Deque or the Doubly ended queue is a data structure or operation performed under queue where insertion and deletion are allowed at both ends. A deque is an ordered collection of...

5 minutes read.

Parameterize Constructor

C++ Parameterized Constructor A constructor having parameters is known as parameterize constructor. Parameterize constructor is used to assign different values. Syntax: className(data-type argument){   // Constructor definition   }   className(data-type argument, data-type argument){   // Constructor definition   } A parameterized constructor can be passed values to constructor function in two ways: 1)...

1 minute read.

How to implement map in C++

Part of the C++ STL is maps (Standard Template Library). Maps are associative containers that hold sorted key-value pairs, where each key is distinct and may only be added or...

4 minutes read.

C++ Forward Iterators

Iterators : Iterators serve as a link between algorithms and STL containers, allowing the data inside the container to be modified. They let you to iterate through the container, access and...

3 minutes read.

For Loop Examples in C++

For Loop A for loop is a repetitive control structure that allows you to create a loop to execute a specific number of times efficiently. The syntax of for loop In C++, a...

6 minutes read.

Differences Between C Structures and C++ Structures

The below table clearly describes the differences between C and C++ programming languages Structures concepts where the core principle concepts like static members, data handling, pointers, access modifiers, the importance...

3 minutes read.

Nullptr in C++

What is Nullptr in C++? A null pointer value is represented by the term nullptr. Use a null pointer value to indicate that a native pointer type, inner pointer, or object...

3 minutes read.