Design Patterns Simplified in Dotnet(With Realtime Examples) - Part 2
Published: 2023-06-06 10:35:43

## Structural Patterns


- Adapter
- Bridge
- Composite 
- Decorator 
- Façade
- Proxy
- Flyweight


The concept of inheritance is used to compose interfaces and define various ways to compose objects for obtaining new functionalities.


Acts as a bridge between two incompatible interfaces.
Involves a single class	called	adapter	which is	responsible for communication between two independent or incompatible interfaces.



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zrpxfwmwjp649xv1hmlx.png)



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5pdj66xi95p6byobfxc3.png)




## Adapter Pattern Examples

- Data Transfer Object (DTO) to Business Object
- Need to convert third party objects to application types
- ADO.NET SqlAdapter, OracleAdapter, MySqlAdapter



in the below  simple example we are converting customer object to customerDto via an adapter, here adapter holds as a bridge 

below is the realtime example 

```csharp
 public class CustomerAdapter : ICustomer
    {
        CustomerManager manager = new CustomerManager();
        public IEnumerable<CustomerDTO> GetCustomers()
        {
            var data = manager.GetData();
            IEnumerable<Customer> customers = JsonConvert.DeserializeObject<IEnumerable<Customer>>(data);

            return customers.Select(x => new CustomerDTO
            {
                CustomerId = x.Id,
                FullName = x.Name,
                AddressDetails = x.Address,
                Mobile = x.Contact
            });
        }
    }


 public class CustomerManager
    {
        private List<Customer> customerList = new List<Customer();
        public CustomerManager()
        {
            customerList.Add(new Customer
            {
                Id = 1,
                Name = "Mohan",
                Address = "Noida",
                Contact = "0000000000"
            });
        }

        public string GetData()
        {
            return JsonConvert.SerializeObject(customerList);
        }
    }


 static void Main(string[] args)
        {
            ICustomer customer = new CustomerAdapter();
            IEnumerable<CustomerDTO> data = customer.GetCustomers();
        }
```


## Bridge Pattern


•Bridge pattern is used to separate an abstraction from its implementation so that both can be modified independently.
•This pattern involves an interface which acts as a bridge between the abstraction class and implementer classes and also makes the functionality of implementer independent from the abstraction.



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fjwxegkc9wj8w4kqrvxd.png)




![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gxnd26makrpr1cgkq64x.png)



## Bridge Pattern Examples


•	Payment Features:
•	Currently Credit Card, DebitCard
•	In Future add more
•	Messaging Features:
•	Currently SMS or Email
•	In Future add more









```csharp


 public interface IMessageSender
    {
        void SendMessage(string To, string Message);
    }


  static void Main(string[] args)
        {
            ApplicationMessage appMsg = new ApplicationMessage();

            appMsg.Text = "Hello, This is Rohith";
            appMsg.To = "0000000000";

            appMsg._sender = new SmsSender();
            appMsg.Send();
        }

 public class ApplicationMessage : Message
    {
        public override void Send()
        {
            _sender.SendMessage(To, Text);
        }
    }

public abstract class Message
    {
        public IMessageSender _sender;
        public string Text;
        public string To;
        public abstract void Send();
    }


 public class SmsSender : IMessageSender
    {
        public void SendMessage(string To, string Message)
        {
            // TO DO:
            Console.WriteLine($"To: {To}, Message: {Message}");
        }
    }


public class EmailSender : IMessageSender
    {
        public void SendMessage(string To, string Message)
        {
            // TO DO:
            Console.WriteLine($"To: {To}, Message: {Message}");
        }
    }
```




## Compostie Pattern

•	Composite pattern is used when we need to treat a group of objects and a single object in the same way.
•	Composite pattern composes objects in term of a tree	structure to represent part as well as whole hierarchies.



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u59kyt61hoebfpoew1r4.png)



## Real  Life Example


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28a3wwihsf0ppuo5ya3q.png)


When you have Interface Label Implementaion like heirarchies then we have this model.


## Composite Pattern Examples

•	File System Folders
•	Managers and Employees
•	Assemblies






```csharp

 static void Main(string[] args)
        {
            Employee ceo = new Employee { Id = 1, Name = "Rahul" };
            Employee manager1 = new Employee { Id = 2, Name = "Amit" };
            Employee manager2 = new Employee { Id = 3, Name = "Mohan" };

            ceo.AddSubordinate(manager1);
            ceo.AddSubordinate(manager2);

            Employee emp1 = new Employee { Id = 3, Name = "Rita" };
            Employee emp2 = new Employee { Id = 4, Name = "Hari" };

            manager1.AddSubordinate(emp2);
            manager1.AddSubordinate(emp1);

            Employee emp3 = new Employee { Id = 5, Name = "Rita" };
            Contractor cont1 = new Contractor { Id = 6, Name = "Hari" };

            manager2.AddSubordinate(emp3);
            manager2.AddSubordinate(cont1);

            Console.WriteLine($"CEO: Id={ceo.Id}, Name={ceo.Name}");
           
            foreach (Employee manager in ceo)
            {
                Console.WriteLine($"  Manager: Id={manager.Id}, Name={manager.Name}");
                Console.WriteLine("      Employee(s):");
                foreach (var emp in manager)
                {
                    Console.WriteLine($"      Id={emp.Id}, Name={emp.Name}");
                }
            }
        }


 public class Employee : IUser, IEnumerable<IUser>
    {
        public int Id { get; set; }
        public string Name { get; set; }

        private List<IUser> _subordinates = new List<IUser>();
        public void AddSubordinate(IUser subordinate)
        {
            _subordinates.Add(subordinate);
        }
        public void RemoveSubordinate(IUser subordinate)
        {
            _subordinates.Remove(subordinate);
        }
        public IUser GetSubordinate(int index)
        {
            return _subordinates[index];
        }

        public IEnumerator<IUser> GetEnumerator()
        {
            foreach (var subordinate in _subordinates)
            {
                yield return subordinate;
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }


public class Contractor: IUser
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }


public interface IUser
    {
        int Id { get; set; }
        string Name { get; set; }
    }




```