انواع دیزاین پترن ها در #C (بخش دوم)
انواع دیزاین پترن ها در C# (بخش دوم)
با سلام و خسته نباشید خدمت شما همراهان همیشگی مجموعه ABLY
در مقاله های قبل تر ما دیزاین پترن و 5 نوع از آن را در سی شارپ به شما معرفی کردیم. حال در این مقاله به 5 نوع دیگر می پردازیم. بنابراین پیشنهاد می کنیم که حتماً مطالب پیش نیاز را مطالعه کنید:
دیزاین پترن (Design Pattern) چیست؟
انواع دیزاین پترن ها در #C (بخش اول)
-
دیزاین پترن Adapter
-
دیزاین پترن Bridge
-
دیزاین پترن Composite
-
دیزاین پترن Decorator
-
دیزاین پترن Facade
انواع دیزاین پترن ها در سی شارپ
انواع دیزاین پترن ها در C# (بخش دوم)
با سلام و خسته نباشید خدمت شما همراهان همیشگی مجموعه ABLY
در مقاله های قبل تر ما دیزاین پترن و 5 نوع از آن را در سی شارپ به شما معرفی کردیم. حال در این مقاله به 5 نوع دیگر می پردازیم. بنابراین پیشنهاد می کنیم که حتماً مطالب پیش نیاز را مطالعه کنید:
-
دیزاین پترن Adapter
-
دیزاین پترن Bridge
-
دیزاین پترن Composite
-
دیزاین پترن Decorator
-
دیزاین پترن Facade
انواع دیزاین پترن ها در سی شارپ
-
دیزاین پترن Adapter | Adapter Design Pattern – C#
الگوی آداپتور اجازه می دهد که یک سیستم از کلاس های دیگری استفاده کند که با آن سازگار نیست. به خصوص برای ابزار و کتابخانه ها استفاده می شود.
بعبارتی (دو اینترفیس ناهمسازگار با کارایی یکسان اما نحوه فراخوانی متفاوت)
الگوی آداپتور به عنوان یک پل بین دو رابط ناسازگار عمل می کند. این الگو شامل یک کلاس واحد به نام آداپتور است که مسئول برقراری ارتباط بین دو رابط مستقل یا ناسازگار است.
برای مثال: یک کارت خوان به عنوان یک آداپتور بین کارت حافظه و لپ تاپ عمل می کند. شما کارت حافظه را به کارت خوان و کارت خوان را به لپ تاپ وصل می کنید تا کارت حافظه را از طریق لپ تاپ بخوانید.
-
نمودار UML و پیاده سازی دیزاین پترن Adapter
کلاس ها و اشیاء در نمودار کلاس UML بالا به شرح زیر هستند:
Itarget
یک اینترفیس (رابط) که توسط کلاینت برای درخواست استفاده می شود.
Adapter
یک کلاس که اینترفیس ITarget را اجرا می کند و کلاس Adaptee را به ارث می برد. این مسئول ارتباط بین کلاینت و Adaptee است.
Adaptee
یک کلاس که دارای قابلیت های مورد نیاز کلاینت است. با این حال، رابط کاربری آن با کلاینت سازگار نیست.
Client
یک کلاس که با نوعی که اینترفیس ITarget را اجرا می کند، تعامل دارد. با این حال، کلاس ارتباطی Adaptee با کلاینت سازگار نیست.
public class Client
{
private ITarget target;
public Client(ITarget target)
{
this.target = target;
}
public void MakeRequest()
{
target.MethodA();
}
}
public interface ITarget
{
void MethodA();
}
public class Adapter : Adaptee, ITarget
{
public void MethodA()
{
MethodB();
}
}
public class Adaptee
{
public void MethodB()
{
Console.WriteLine("MethodB() is called");
}
}
مثال:
رابط ها و اشیاء در نمودار بالا به شرح زیر هستند:
- ITraget - Target interface
- Employee Adapter- Adapter Class
- HR System- Adaptee Class
- ThirdPartyBillingSystem – Client
///
/// The 'Client' class
///
public class ThirdPartyBillingSystem
{
private ITarget employeeSource;
public ThirdPartyBillingSystem(ITarget employeeSource)
{
this.employeeSource = employeeSource;
}
public void ShowEmployeeList()
{
List employee = employeeSource.GetEmployeeList();
//To DO: Implement you business logic
Console.WriteLine("######### Employee List ##########");
foreach (var item in employee)
{
Console.Write(item);
}
}
}
///
/// The 'ITarget' interface
///
public interface ITarget
{
List GetEmployeeList();
}
///
/// The 'Adaptee' class
///
public class HRSystem
{
public string[][] GetEmployees()
{
string[][] employees = new string[4][];
employees[0] = new string[] { "100", "Deepak", "Team Leader" };
employees[1] = new string[] { "101", "Rohit", "Developer" };
employees[2] = new string[] { "102", "Gautam", "Developer" };
employees[3] = new string[] { "103", "Dev", "Tester" };
return employees;
}
}
///
/// The 'Adapter' class
///
public class EmployeeAdapter : HRSystem, ITarget
{
public List GetEmployeeList()
{
List employeeList = new List();
string[][] employees = GetEmployees();
foreach (string[] employee in employees)
{
employeeList.Add(employee[0]);
employeeList.Add(",");
employeeList.Add(employee[1]);
employeeList.Add(",");
employeeList.Add(employee[2]);
employeeList.Add("\n");
}
return employeeList;
}
}
///
/// Adapter Design Pattern Demo
///
class Program
{
static void Main(string[] args)
{
ITarget Itarget = new EmployeeAdapter();
ThirdPartyBillingSystem client = new ThirdPartyBillingSystem(Itarget);
client.ShowEmployeeList();
Console.ReadKey();
}
}
خروجی کد بالا:
-
دیزاین پترن Bridge | Bridge Design Pattern – C#
همه ما می دانیم، به ارث بردن یک راه برای مشخص کردن پیاده سازی های مختلف یک انتزاع (abstraction) است. در صورتی که بیش از یک متد abstract داشته باشیم و روش های مختلفی برای پیاده سازی آنها وجود داشته باشد، آنگاه باید برای هر نسخه abstract یک کلاس جدید ایجاد کرد و در آخر ممکن است با کلاس های زیادی مواجه شویم. الگوی Bridge برای حل این مشکل یک راه حل ارائه کرده است. در این الگو یک اینترفیس به عنوان یک پل (Bridge) بین کلاس های Abstract و معمولی، معرفی می شود.
الگوی پل برای جداسازی abstract از پیاده سازی آن استفاده می شود. به طوری که هر دو می توانند به صورت مستقل تغییر داده شوند.
این الگو شامل یک رابط است که به عنوان یک پل بین کلاس abstract و کلاس های پیاده سازی عمل می کند و همچنین کلاس پیاده سازی را مستقل از کلاس abstract می کند. هر دو نوع کلاس ها را می توان بدون تاثیر بر یکدیگر اصلاح کرد.
-
نمودار UML و پیاده سازی دیزاین پترن Bridge
کلاس ها و اشیاء در نمودار کلاس UML بالا به شرح زیر هستند:
Abstraction
کلاسی که با client سرو کار دارد. این کلاس ارجاع یک شی از نوع Implementor را نگهداری می کند.
Redefined Abstraction
یک کلاس که از کلاس Abstraction به ارث می برد تا چندین نسخه از متدهای abstract داشته باشد.
Bridge
یک رابط که به عنوان یک پل بین کلاس abstract و کلاسهای پیاده سازی عمل می کند و همچنین کلاس پیاده سازی را مستقل از کلاس انتزاع ) abstract ( می کند.
ImplementationA & ImplementationB
کلاس هایی هستند که رابط Bridge را اجرا می کنند و همچنین جزئیات پیاده سازی مربوط به کلاس Abstraction مرتبط را ارائه می دهند.
public abstract class Abstraction
{
public Bridge Implementer { get; set; }
public virtual void Operation()
{
Console.WriteLine("ImplementationBase:Operation()");
Implementer.OperationImplementation();
}
}
public class RefinedAbstraction : Abstraction
{
public override void Operation()
{
Console.WriteLine("RefinedAbstraction:Operation()");
Implementer.OperationImplementation();
}
}
public interface Bridge
{
void OperationImplementation();
}
public class ImplementationA : Bridge
{
public void OperationImplementation()
{
Console.WriteLine("ImplementationA:OperationImplementation()");
}
}
public class ImplementationB : Bridge
{
public void OperationImplementation()
{
Console.WriteLine("ImplementationB:OperationImplementation()");
}
}
مثال:
رابط ها و اشیاء در نمودار بالا به شرح زیر هستند:
- Message - Abstraction Class.
- SystemMessage & UserMessage- Redefined Abstraction Classes.
- IMessageSender- Bridge Interface.
- EmailSender, WebServiceSender & MSMQ Sender- ConcreteImplementation class which implements the IMessageSender interface.
///
/// The 'Abstraction' class
///
public abstract class Message
{
public IMessageSender MessageSender { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public abstract void Send();
}
///
/// The 'RefinedAbstraction' class
///
public class SystemMessage : Message
{
public override void Send()
{
MessageSender.SendMessage(Subject, Body);
}
}
///
/// The 'RefinedAbstraction' class
///
public class UserMessage : Message
{
public string UserComments { get; set; }
public override void Send()
{
string fullBody = string.Format("{0}\nUser Comments: {1}", Body, UserComments);
MessageSender.SendMessage(Subject, fullBody);
}
}
///
/// The 'Bridge/Implementor' interface
///
public interface IMessageSender
{
void SendMessage(string subject, string body);
}
///
/// The 'ConcreteImplementor' class
///
public class EmailSender : IMessageSender
{
public void SendMessage(string subject, string body)
{
Console.WriteLine("Email\n{0}\n{1}\n", subject, body);
}
}
///
/// The 'ConcreteImplementor' class
///
public class MSMQSender : IMessageSender
{
public void SendMessage(string subject, string body)
{
Console.WriteLine("MSMQ\n{0}\n{1}\n", subject, body);
}
}
///
/// The 'ConcreteImplementor' class
///
public class WebServiceSender : IMessageSender
{
public void SendMessage(string subject, string body)
{
Console.WriteLine("Web Service\n{0}\n{1}\n", subject, body);
}
}
///
/// Bridge Design Pattern Demo
///
class Program
{
static void Main(string[] args)
{
IMessageSender email = new EmailSender();
IMessageSender queue = new MSMQSender();
IMessageSender web = new WebServiceSender();
Message message = new SystemMessage();
message.Subject = "Test Message";
message.Body = "Hi, This is a Test Message";
message.MessageSender = email;
message.Send();
message.MessageSender = queue;
message.Send();
message.MessageSender = web;
message.Send();
UserMessage usermsg = new UserMessage();
usermsg.Subject = "Test Message";
usermsg.Body = "Hi, This is a Test Message";
usermsg.UserComments = "I hope you are well";
usermsg.MessageSender = email;
usermsg.Send();
Console.ReadKey();
}
}
خروجی کد بالا:
-
دیزاین پترن Composite | Composite Design Pattern – C#
الگوی کامپوزیت زمانی استفاده می شود که ما نیاز به تغییر یک گروه از اشیاء و یک شی به طور یکسان داشته باشیم. الگوی کامپوزیت اجسام را به ترتیب از یک ساختار درخت برای نشان دادن بخشی و همچنین سلسله مراتب کامل تشکیل می دهد.
بعبارتی یک نمایش سلسله مراتبی جزء به کل را ارائه می دهد.
-
نمودار UML و پیاده سازی دیزاین پترن Composite
کلاس ها و اشیاء در نمودار کلاس UML بالا به شرح زیر هستند:
Component
این به عنوان یک اینترفیس برای تمام اشیاء درون سلسله مراتب عمل می کند.
Composite
متدهای موردنیاز برای مدیریت متدهای فرزندانش. مانند متدهای: Add,Remove,Find و Get
Leaf
نگهداری متدهای رایج در components
public interface Component
{
void Operation();
}
public class Composite : Component, IEnumerable
{
private List _children = new List();
public void AddChild(Component child)
{
_children.Add(child);
}
public void RemoveChild(Component child)
{
_children.Remove(child);
}
public Component GetChild(int index)
{
return _children[index];
}
public void Operation()
{
string message = string.Format("Composite with {0} child(ren)", _children.Count);
Console.WriteLine(message);
}
public IEnumerator GetEnumerator()
{
foreach (Component child in _children)
yield return child;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class Leaf : Component
{
public void Operation()
{
Console.WriteLine("Leaf");
}
}
مثال:
رابط ها و اشیاء در نمودار بالا به شرح زیر هستند:
- IEmployed - Component Interface.
- Employee- Composite Class.
- Contractor- Leaf Class.
///
/// The 'Component' Treenode
///
public interface IEmployed
{
int EmpID { get; set; }
string Name { get; set; }
}
///
/// The 'Composite' class
///
public class Employee : IEmployed, IEnumerable
{
private List _subordinates = new List();
public int EmpID { get; set; }
public string Name { get; set; }
public void AddSubordinate(IEmployed subordinate)
{
_subordinates.Add(subordinate);
}
public void RemoveSubordinate(IEmployed subordinate)
{
_subordinates.Remove(subordinate);
}
public IEmployed GetSubordinate(int index)
{
return _subordinates[index];
}
public IEnumerator GetEnumerator()
{
foreach (IEmployed subordinate in _subordinates)
{
yield return subordinate;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
///
/// The 'Leaf' class
///
public class Contractor : IEmployed
{
public int EmpID { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
Employee Rahul = new Employee { EmpID = 1, Name = "Rahul" };
Employee Amit = new Employee { EmpID = 2, Name = "Amit" };
Employee Mohan = new Employee { EmpID = 3, Name = "Mohan" };
Rahul.AddSubordinate(Amit);
Rahul.AddSubordinate(Mohan);
Employee Rita = new Employee { EmpID = 4, Name = "Rita" };
Employee Hari = new Employee { EmpID = 5, Name = "Hari" };
Amit.AddSubordinate(Rita);
Amit.AddSubordinate(Hari);
Employee Kamal = new Employee { EmpID = 6, Name = "Kamal" };
Employee Raj = new Employee { EmpID = 7, Name = "Raj" };
Contractor Sam = new Contractor { EmpID = 8, Name = "Sam" };
Contractor tim = new Contractor { EmpID = 9, Name = "Tim" };
Mohan.AddSubordinate(Kamal);
Mohan.AddSubordinate(Raj);
Mohan.AddSubordinate(Sam);
Mohan.AddSubordinate(tim);
Console.WriteLine("EmpID={0}, Name={1}", Rahul.EmpID, Rahul.Name);
foreach (Employee manager in Rahul)
{
Console.WriteLine("\n EmpID={0}, Name={1}", manager.EmpID, manager.Name);
foreach (var employee in manager)
{
Console.WriteLine(" \t EmpID={0}, Name={1}", employee.EmpID, employee.Name);
}
}
Console.ReadKey();
}
}
خروجی کد بالا:
-
دیزاین پترن Decorator | Decorator Design Pattern - C#
الگوی Decorator برای افزودن قابلیت های جدید به یک شیء موجود بدون تغییر ساختار آن استفاده می شود.
این الگو یک کلاس Decorator ایجاد می کند که کلاس اصلی را پر می کند و رفتار / عملیات جدید را به یک شی در زمان اجرا اضافه می کند.
در یک خط – در این الگو یکسری مسئولیت های اضافی به یک شی واگذار می شود.
-
نمودار UML و پیاده سازی دیزاین پترن Decorator
کلاس ها و اشیاء در نمودار کلاس UML بالا به شرح زیر هستند:
Component
این یک رابط کاربری است که توسط ConcreteClass و Decorator اجرا می شود.
ConcreteComponent
یک کلاس که رابط کامپوننت را اجرا می کند.
Decorator
یک کلاس abstract است که Component را نیز پیاده سازی می کند.
ConcreteDecorator
برای پیاده سازی Decorator بکار میرود.
public interface Component
{
void Operation();
}
public class ConcreteComponent : Component
{
public void Operation()
{
Console.WriteLine("Component Operation");
}
}
public abstract class Decorator : Component
{
private Component _component;
public Decorator(Component component)
{
_component = component;
}
public virtual void Operation()
{
_component.Operation();
}
}
public class ConcreteDecorator : Decorator
{
public ConcreteDecorator(Component component) : base(component) { }
public override void Operation()
{
base.Operation();
Console.WriteLine("Override Decorator Operation");
}
}
مثال:
رابط ها و اشیاء در نمودار بالا به شرح زیر هستند:
- Vehicle - Component Interface.
- HondaCity- ConcreteComponent class.
- VehicleDecorator- Decorator Class.
- Special Offer- ConcreteDecorator class.
///
/// The 'Component' interface
///
public interface Vehicle
{
string Make { get; }
string Model { get; }
double Price { get; }
}
///
/// The 'ConcreteComponent' class
///
public class HondaCity : Vehicle
{
public string Make
{
get { return "HondaCity"; }
}
public string Model
{
get { return "CNG"; }
}
public double Price
{
get { return 1000000; }
}
}
///
/// The 'Decorator' abstract class
///
public abstract class VehicleDecorator : Vehicle
{
private Vehicle _vehicle;
public VehicleDecorator(Vehicle vehicle)
{
_vehicle = vehicle;
}
public string Make
{
get { return _vehicle.Make; }
}
public string Model
{
get { return _vehicle.Model; }
}
public double Price
{
get { return _vehicle.Price; }
}
}
///
/// The 'ConcreteDecorator' class
///
public class SpecialOffer : VehicleDecorator
{
public SpecialOffer(Vehicle vehicle) : base(vehicle) { }
public int DiscountPercentage { get; set; }
public string Offer { get; set; }
public double Price
{
get
{
double price = base.Price;
int percentage = 100 - DiscountPercentage;
return Math.Round((price * percentage) / 100, 2);
}
}
}
///
/// Decorator Pattern Demo
///
class Program
{
static void Main(string[] args)
{
// Basic vehicle
HondaCity car = new HondaCity();
Console.WriteLine("Honda City base price are : {0}", car.Price);
// Special offer
SpecialOffer offer = new SpecialOffer(car);
offer.DiscountPercentage = 25;
offer.Offer = "25 % discount";
Console.WriteLine("{1} @ Diwali Special Offer and price are : {0} ", offer.Price, offer.Offer);
Console.ReadKey();
}
}
خروجی کد بالا:
-
دیزاین پترن Facade | Facade Design Pattern – C#
الگوی Facade پیچیدگی های سیستم را پنهان می کند و یک رابط را برای کلاینت فراهم می کند که از طریق آن مشتری می تواند به سیستم دسترسی پیدا کند.
الگوی Facade هنگامی استفاده می شود که یک سیستم بسیار پیچیده یا دشوار است. زیرا سیستم دارای تعداد زیادی کلاس های وابسته است یا کد منبع آن در دسترس نیست.
در یک خط - Facade یک اینترفیس سطح بالاتر است که استفاده از SubSystem را راحت تر می کند
-
نمودار UML و پیاده سازی دیزاین پترن Facade
کلاس ها و اشیاء در نمودار کلاس UML بالا به شرح زیر هستند:
Complex System
یک کتابخانه از subsystems
SubsystemA, SubsystemB, SubsystemC
این کلاس ها در سیستم پیچیده هستند و عملیات دقیق را ارائه می دهند.
Façade
یک اینترفیس (یا یک کلاس پوشاننده-Wrapper) برای رفع تمام درخواست های Client
Client
یک کلاس که عملیات سطح بالا در Façade را فراخوانی می کند.
class SubsystemA
{
public string OperationA1()
{
return "Subsystem A, Method A1\n";
}
public string OperationA2()
{
return "Subsystem A, Method A2\n";
}
}
class SubsystemB
{
public string OperationB1()
{
return "Subsystem B, Method B1\n";
}
public string OperationB2()
{
return "Subsystem B, Method B2\n";
}
}
class SubsystemC
{
public string OperationC1()
{
return "Subsystem C, Method C1\n";
}
public string OperationC2()
{
return "Subsystem C, Method C2\n";
}
}
public class Facade
{
SubsystemA a = new SubsystemA();
SubsystemB b = new SubsystemB();
SubsystemC c = new SubsystemC();
public void Operation1()
{
Console.WriteLine("Operation 1\n" +
a.OperationA1() +
a.OperationA2() +
b.OperationB1());
}
public void Operation2()
{
Console.WriteLine("Operation 2\n" +
b.OperationB2() +
c.OperationC1() +
c.OperationC2());
}
}
مثال:
رابط ها و اشیاء در نمودار بالا به شرح زیر هستند:
- CarModel, CarEngine, CarBody, CarAccessories - These are subsystems.
- CarFacade- Facade class.
///
/// The 'Subsystem ClassA' class
///
class CarModel
{
public void SetModel()
{
Console.WriteLine(" CarModel - SetModel");
}
}
///
/// The 'Subsystem ClassB' class
///
class CarEngine
{
public void SetEngine()
{
Console.WriteLine(" CarEngine - SetEngine");
}
}
///
/// The 'Subsystem ClassC' class
///
class CarBody
{
public void SetBody()
{
Console.WriteLine(" CarBody - SetBody");
}
}
///
/// The 'Subsystem ClassD' class
///
class CarAccessories
{
public void SetAccessories()
{
Console.WriteLine(" CarAccessories - SetAccessories");
}
}
///
/// The 'Facade' class
///
public class CarFacade
{
CarModel model;
CarEngine engine;
CarBody body;
CarAccessories accessories;
public CarFacade()
{
model = new CarModel();
engine = new CarEngine();
body = new CarBody();
accessories = new CarAccessories();
}
public void CreateCompleteCar()
{
Console.WriteLine("******** Creating a Car **********\n");
model.SetModel();
engine.SetEngine();
body.SetBody();
accessories.SetAccessories();
Console.WriteLine("\n******** Car creation complete **********");
}
}
///
/// Facade Pattern Demo
///
class Program
{
static void Main(string[] args)
{
CarFacade facade = new CarFacade();
facade.CreateCompleteCar();
Console.ReadKey();
}
}
خروجی کد بالا:
"منتشر شده در سایت ABLY"