Tuesday, January 25, 2022

Gang of Four(GoF) Design Patterns in .NET

 The four authors Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides are collectively introduced Gang of Four Design Patterns in Software development. In 1994, they published a book (Design Patterns: Elements of Reusable Object-Oriented Software) for explaining the concept of Design Patterns.

Gang of Four(GOF) Design Patterns

The 23 Design patterns are defined by the Gang of Four programmers. These 23 patterns are divided into three groups depending on the nature of the design problem they intend to solve.

  1. Creational Design Patterns

    These patterns deal with the process of objects creation in such a way that they can be decoupled from their implementing system. This provides more flexibility in deciding which objects need to be created for a given use case/ scenario. There are as follows:

    1. Factory Method : Create instances of derived classes

    2. Abstract Factory : Create instances of several classes belonging to different families

    3. Builder : Separates an object construction from its representation

    4. Prototype : Create a duplicate object or clone of the object

    5. Singleton : Ensures that a class can has only one instance

  2. Structural Design Patterns

    These patterns deal with the composition of objects structures. The concept of inheritance is used to compose interfaces and define various ways to compose objects for obtaining new functionalities. There are as follows:

    1. Adapter : Match interfaces of different classes

    2. Bridge : Separates an object’s abstraction from its implementation

    3. Composite : A tree structure of simple and composite objects

    4. Decorator : Add responsibilities to objects dynamically

    5. Façade : A single class that represents an entire complex system

    6. Flyweight : Minimize memory usage by sharing as much data as possible with similar objects

    7. Proxy : Provides a surrogate object, which references to other object

  3. Behavioral Design Patterns

    These patterns deal with the process of communication, managing relationships, and responsibilities between objects. There are as follows:

    1. Chain of Responsibility: Passes a request among a list or chain of objects.

    2. Command: Wraps a request under an object as a command and passed to invoker object.

    3. Interpreter: Implements an expression interface to interpret a particular context.

    4. Iterator: Provides a way to access the elements of a collection object in sequential manner without knowing its underlying structure.

    5. Mediator: Allows multiple objects to communicate with each other’s without knowing each other’s structure.

    6. Memento: Capture the current state of an object and store it in such a manner that it can be restored at a later time without breaking the rules of encapsulation.

    7. Observer: Allows an object (subject) to publish changes to its state and other objects (observer) that depend upon that object are automatically notified of any changes to the subject's state.

    8. State: Alters the behavior of an object when it’s internal state changes.

    9. Strategy: Allows a client to choose an algorithm from a family of algorithms at run-time and gives it a simple way to access it.

    10. Visitor: Creates and performs new operations onto a set of objects without changing the object structure or classes.

    11. Template Method: Defines the basic steps of an algorithm and allow the implementation of the individual steps to be changed.

Multi-Level Inheritance in C#

 It is 2nd Part of  Inheritance in C# for Multi-Level

Generally, c# supports only single inheritance that means a class can only inherit from one base class. However, in c# the inheritance is transitive, and it allows you to define a hierarchical inheritance for a set of types, and it is called a multi-level inheritance.

 

For example, if class C is derived from class B, and class B is derived from class A, then class C inherits the members declared in both class B and class A.


public class A
{
// Implementation
}
public class B: A
{
// Implementation
}
public class C: B
{
// Implementation
}


If you observe the above code snippet, class C is derived from class B, and class B is derived from class A, then class C inherits the members declared in both class B and class A. This is how we can implement multi-level inheritance in our applications.


Multi-Level Inheritance Example

Following is the example of implementing multi-level inheritance in the c# programming language.

using System;

namespace ArjunInheritance
{
    public class A
    {
       public string Name;
       public void GetName()
       {
          Console.WriteLine("Name: {0}", Name);
       }
    }
    public class B: A
    {
       public string Location;
       public void GetLocation()
       {
          Console.WriteLine("Location: {0}", Location);
       }
    }
    public class C: B
    {
       public int Age;
       public void GetAge()
       {
          Console.WriteLine("Age: {0}", Age);
       }
    }
    class Program
    {
       static void Main(string[] args)
       {
          C c = new C();
          c.Name = "Arjun Walmiki";
          c.Location = "Thane";
          c.Age = 35;
          c.GetName();
          c.GetLocation();
          c.GetAge();
          Console.WriteLine("\nPress Any Key to Exit..");
          Console.ReadLine();
       }
    }
}

If you observe the above example, we implemented three classes (ABC), and class C is derived from class B, and class B is derived from class A.

 

By implementing a multi-level inheritance, class C can inherit the members declared in class B and class A.

 

When you execute the above c# program, you will get the result as shown below.


Name : Arjun Walmiki

Location : Thane

Age : 35

Press Any Key to Exit..


Multiple Inheritance

As discussed, c# supports only single inheritance that means a class can only inherit from one base class. If we try to inherit a class from multiple base classes, then we will get compile-time errors.

 

For example, if class C is trying to inherit from Class A and B simultaneously, we will get a compile-time error because multiple inheritance is not allowed in c#.

public class A
{
// Implementation
}
public class B
{
// Implementation
}
public class C: A, B
{
// Implementation

}

If you observe the above code snippet, class C is trying to inherit properties from both classes A and B simultaneously, which will lead to compile-time errors like “Class C cannot have multiple classes: A and B”.

 

As discussed, multi-level inheritance is supported in c#, but multiple inheritance is not supported. If you want to implement multiple inheritance in c#, we can achieve this by using interfaces. In the next chapters, we will learn how to use interfaces to achieve multiple inheritance in a detailed manner. 

Inheritance in C#

 In c#, Inheritance is one of the primary concepts of object-oriented programming (OOP), and it is used to inherit the properties from one class (base) to another (child) class.

In c# inheritance, the class whose members are inherited is called a base (parentclass, and the class that inherits the members of the base (parent) class is called a derived (childclass.


Following is the syntax of implementing an inheritance

<access_modifier> class <base_class_name>
{
// Base class Implementation
}

<access_modifier> class <derived_class_name> : <base_class_name>
{
// Derived class implementation
}

Example:-

public class x
{
    public void GetDetails()
    {
       // Method implementation
    }
}
public class Y: X
{
    // your class implementation
}
class Program
{
   static void Main(string[] args)
   {
       Y y = new Y();
       y.GetDetails();
   }
}

If you observe the above example, we defined a class “X” with the method called “GetDetails” and the class “Y” is inheriting from class “X”. After that, we call a “GetDetails” method by using an instance of derived class “Y”.

Example 2:-

using System;

namespace ArjunInheritanceExample
{
    public class User
    {
       public string Name;
       private string Location;
       public User()
       {
          Console.WriteLine("Base Class Constructor");
       }
       public void GetUserInfo(string loc)
       {
          Location = loc;
          Console.WriteLine("Name: {0}", Name);
          Console.WriteLine("Location: {0}", Location);
       }
    }
    public class Details: User
    {
       public int Age;
       public Details()
       {
          Console.WriteLine("Child Class Constructor");
       }
       public void GetAge()
       {
          Console.WriteLine("Age: {0}", Age);
       }
    }
    class Program
    {
       static void Main(string[] args)
       {
          Details d = new Details();
          d.Name = "Arjun Walmiki";
          // Compile Time Error
          //d.Location = "Thane";
          d.Age = 35;
          d.GetUserInfo("Thane");
          d.GetAge();
          Console.WriteLine("\nPress Any Key to Exit..");
          Console.ReadLine();
       }
    }
}

If you observe the above example, we defined a base class called “User” and inheriting all the user class properties into a derived class called “Details” and we are accessing all the members of the User class with an instance of the Details class.

 

If we uncomment the commented code, we will get a compile-time error because the Location property in the User class is defined with a private access modifier. The private members can be accessed only within the class.

 

When you execute the above c# program, you will get the result as shown below.


Base Class Constructor

Child Class Constructor

Name : Arjun Walmiki

Location : Thane

Age : 35

Press Any Key to Exit..


If you observe the above result, we are able to access all the properties of base class into child class based on our requirements.