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.
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
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.
Bridge Pattern Examples
• Payment Features:
• Currently Credit Card, DebitCard
• In Future add more
• Messaging Features:
• Currently SMS or Email
• In Future add more
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.
Real Life Example
When you have Interface Label Implementaion like heirarchies then we have this model.
Composite Pattern Examples
• File System Folders
• Managers and Employees
• Assemblies
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; }
}