آشنایی با Strategy Design Pattern

در این مقاله می خواهیم، یکی دیگر از الگوهای طراحی شی گرا با نام الگوی Strategy را توضیح دهیم.این الگو یک الگوی رفتاری یا Behavioral می باشد. الگوهای رفتاری با الگوریتم ها و تعامل بین آن ها درگیر می باشند. اگر برنامه ما یک الگوریتم یکتا را پیاده سازی می کند ممکن است به خاطر بالا رفتن پیچیدگی مدیریت برنامه و نگهداری کد شود. ما با استفاده از الگوهای طراحی رفتاری سعی می کنیم که از این پیچیدگی ها کم کنیم.

آشنایی با Strategy Design Pattern

در سری الگوهای طراحی(design pattern) رفتاری یا behavioral، الگوی طراحی Strategy یکی از آنهایی است که به طور گسترده استفاده می شود. الگوی Strategy یک مثال خوب برای اصول اولیه طراحی شیئ گرای SOLID می باشد. برای درک بیشتر اجازه دهید ابتدا توضیح دهیم که Strategy Pattern چیست؟

تعریف

الگوی طراحی Strategy یک الگوریتم را از کلاس میزبان جدا کرده و در کلاس دیگر نگه می دارد. شاید ما در برنامه خود چندین الگوریم Strategy داشته باشیم، حال اگر بخواهیم همه آنها را در برنامه خود داشته باشیم باید از عبارت های شرطی بسیاری استفاده کنیم که این خود باعث می شود که پیچیدگی برنامه بالا برود. الگوریتم استراتژی این امکان را ایجاد می کند که کاربر از میان گروهی از الگوریتم ها، یک الگوریتم را برای استفاده انتخاب کند.

الگوی strategy خانواده ای از الگوریتم های مرتبط را تعریف می کند به طور مثال الگوریتم مرتب سازی که شامل الگوریتم های مرتب سازی حبابی، مرتب سازی سریع، مرتب سازی درجی و مرتب سازی ادغامی می باشند؛ یا الگوریتم فشرده سازی که شامل zipو gzip, tar, jar می باشند و یا الگوریتم های رمزنگاری به طور مثال رمزگذاری 128 بیتی، AES. SHA و غیره هستند که آن ها می توانند به طور مستقل عمل کنند، هرکدام از این الگوریتم ها می توانند در شرایط خاصی بهترین انتخاب موجود باشند. می توان تصمیم گیری این شرایط را با استفاده از الگوی strategy پیاده سازی کرد.

به عنوان مثال، الگوی Strategy می تواند برای مرتب سازی اعداد استفاده شود و به کلاینت اجازه می دهد که هر نوع الگوریتم مرتب سازی را در زمان اجرا انتخاب کند و این کار بدون اینکه کلاس را تغییر دهیم، انجام می شود. بنابراین الگوی Strategy، انعطاف پذیری، توسعه پذیری و امکان انتخاب را برای کاربر فراهم می کند. به این شکل که مجموعه ای از ورودی ها داریم ولی هرکدام از روش های مرتب سازی را به صورت جداگانه پیاده سازی می کنیم. در این صورت با توجه به شرایط، وروردی ها را به یک الگوریتم داده و خروجی آن را دریافت خواهیم کرد. 

مثال:

در اینجا فرض می کنیم که یک متن برای رمزنگاری داریم. هدف انتخاب الگوریتم های رمزنگاری بر اساس کارایی آنها می باشد به طور مثال انتخاب الگوریتمی که برای رمزنگاری متن های بلند یا کوتاه موثر و مفید است.

در ابتدا، باید به کاربران توجه شود که چگونه داده رمزنگاری می شود یا در اصل کدام ساختار داده داخلی برای رمزنگاری داده ها استفاده می شود. واقع سوال این است که چگونه می توان یک راه حل طراحی کرد که فقط در موقعیت خود مناسب باشند. برای این کار به انواع مختلف الگوریتم های رمزنگاری احتیاج داریم.

راه حل:

الگوی طراحی راه حلی برای رفع مشکل فوق فراهم می کند و کمک می کند که درگیر داده های پیچیده نشویم.

موارد استفاده شده:

الگوریتم رمزنگاری(Abstract Strategy)

 یک اینترفیس مشترک برای تمام الگوریتم های پشتیبانی شده اعلان می شود. Context  از این اینترفیس برای فراخوانی الگوریتم های تعریف شده توسط ConcreteStrategy استفاده می کند.

ConcreteStrategy (رمزنگاری 128 بیتی، ShaEncryption)

الگوریتم را با استفاده از اینترفیس strategy می توان پیاده سازی کرد.

کلاس هایی که در این الگوی طراحی استفاده می شود به صورت زیر هستند:

Context: کلاسی که اطلاعات ساختاری برای اشیا IStrategy را در خود نگه می دارد. همان قسمتی از برنامه است که نوع استراتژی را انتخاب می کند. 

IStrategy: یک اینترفیس مشترک بین همه ی استراتژی ها تعریف می کند.

StartegyA,StrategyB کلاس هایی که شامل الگوریتم های پیاده شده از اینترفیس IStrategy می باشد.

Context

_ با یک شیئ ConcreteStrategy پیکربندی شده است.

_ یک رفرنس برای شیئ Strategy نگه می دارد.

_ یک اینترفیس تعریف می کند که به Strategy اجازه دسترسی به داده ها را می دهد.

Strategy و context برای پیاده سازی الگوریتم انتخابی در تعامل هستند. یک context ممکن است تمام داده های مورد نیاز را زمانی که strategy فراخوانی شود، توسط الگوریتم به strategy ارسال کند. یک context درخواست ها را از کلاینت ها به strategy خود forward می کند.

کلاینت ها معمولا یک شیئ ConcreteStrategy را برای context ایجاد و ارسال می کنند و پس از آن کلاینت ها با context به صورت منحصر به فرد در تعامل هستند.

برخی نکات کلیدی درباره پیاده سازی الگوی Strategy به صورت زیر هستند:

_ اغلب کلاس context  شامل عبارت Switching یا تعویض الگوریتم یا چند دستور شرطی تو در تو می باشد تا در شرایط متفاوت تصمیماتی گرفته شود.

_ اگر بخواهیم برنامه را بعدا گسترش دهیم و الگوریتم های جدیدی توسط کاربران به برنامه اضافه کنیم می توانیم از Extebtion method ها استفاده کنیم.

_ اگر استراتژی ها ساده هستند می توانند به شکل delegate پیاده سازی شوند و نیازی به ساختن کلاس نیست.

_ یکی از موارد استفاده از الگوی Strategy استفاده از این الگو در پیاده سازی تکنولوژی Linq در زبان #C می باشد که می توان به راحتی برای انواع پایگاه داده و انواع مجموعه داده ها از آن استفاه کرد.

به طور کلی در زمان های زیر از الگوی Strategy استفاده می کنیم:
زمانی که کلاس های مرتبط زیادی داشته باشیم و این کلاس ها فقط در رفتارشان متفاوت باشند.

زمانی که برای انجام کاری الگوریتم های متفاوتی موجود باشد و بتوان شرایط انتخاب الگوریتم را توسط کدنویسی مشخص کرد.

زمانی که الگوریتم از داده هایی استفاده می کند که استفاده کننده ها نباید به آن کد دسترسی داشته باشند.

زمانی پیش می آید که Context نمی خواهد از هیچکدام از استراتژی های موجود استفاده کند در این صورت می گوییم که Context از استراتژی do nothing استفاده می کند، یعنی هیچ کاری انجام نمی دهد. 

برای درک بهتر مفاهیم بالا مثال ضمیمه شده به این مقاله رابررسی کنید.

آموزش سی شارپ

فایل های ضمیمه
دانلود نسخه ی PDF این مطلب