استفاده صحیح از قواعد شی‌گرایی [Polymorphism]
تاریخ انتشار:۱۰:۰ ۱۳۹۸/۹/۲۳

استفاده صحیح از قواعد شی‌گرایی [Polymorphism]


    




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


یکی از این اصول Polymorphism یا چندریختی هست. شما وقتی کلاس هایی داری که ذاتا یکی هستن ولی عملکردهای مختلفی دارن، خوب مسلما باید یک کلاس والد داشته باشی و برای عملکردهای خاص و مختلف ارث بری های مختلف داشته باشید. اجازه بدید با یه مثال ادامه بدیم که موضوع کامل مشخص باشه.

کلاس و کد زیر رو رد نظر بگیرید.

  1. public enum MessageType
  2. }
  3. ,Success
  4. Failure
  5. {
  6. public class Message
  7. }
  8. public string MessageText { get; set; }
  9. public MessageType Type { get; set; }
  10. {
  11. class Program
  12. }
  13. static void Main ( string [ ] args )
  14. }
  15. Message msg = new Message ( ) { MessageText= "Success" ,Type =MessageType.Success }
  16. ;ShowMessage ( msg )
  17. {

  18. private static void ShowMessage ( Message msg )
  19. }
  20. switch ( msg.Type )
  21. }
  22. :case MessageType.Success
  23. ;()ShowGreenMessage
  24. ;break
  25. :case MessageType.Failure
  26. ;()ShowRedMessage
  27. ;break
  28. :default
  29. ;break
  30. {
  31. {

  32. ()private static void ShowGreenMessage
  33. }
  34. ;()throw new NotImplementedException
  35. {

  36. ()private static void ShowRedMessage
  37. }
  38. ;()throw new NotImplementedException
  39. {
  40. {




در این تکه کد ما کلاسی داریم به اسم Message که میتونه از نوع Success و یا Failure باشه. حالا در برنامه و موقع نمایش تصمیم میگیریم که با توجه به اینکه این کلاس از چه جنسی هست به چه رنگی نمایش داده شود.

اینجا مشکلاتی وجود داره. اولا که هرجا بخایم نمایش داشته باشیم باید تصمیم گیری رو انجام بدیم، شاید بگید که میشه یه تابع تعریف کنیم و اونو صدا بزنیم. اما هنوز یه مشکل دیگه هست. اصل encapsulation که زیر سوال رفته را چه کنیم؟! قسمتی از عملکرد کلاس ما که باید داخل کلاس انجام بشه به بیرون نشت کرده. یه مشکل دیگه هم هست. من وقتی دارم کد شما را review میکنم برام مهم نیست که موقع نمایش پیام چه رنگی را نمایش میدهید. صرفا دانستن اینکه پیام نمایش میدهید برای من کافی است، الباقی ماجرا جزئیاتی است که به شما و کدتان مربوط است. میبینید قابلیت خوانایی هم پایین اومده و با ادامه این روند خوانایی و نگهداری کد پایین و پایین تر می آید.

حالا وقت کمی refactor هست. پس ساختار کلاسمان را به شکل زیر تغییر میدهیم.


  1. class Program
  2. }
  3. static void Main ( string [ ] args )
  4. }
  5. MessageRefactor msg = new SuccessMessage ( ) { MessageText= "Success" } ;
  6. ;()msg. ShowMessage
  7. {

  8. {

  9. public abstract class MessageRefactor
  10. }
  11. public string MessageText { get; set; }
  12. ;()public abstract void ShowMessage
  13. }

  14. public class SuccessMessage : MessageRefactor
  15. }

  16. ()public override void ShowMessage
  17. }
  18. ;()ShowGreenMessage
  19. {

  20. ()private void ShowGreenMessage
  21. }
  22. ;()throw new NotImplementedException
  23. {
  24. {
  25. public class FailureMessage : MessageRefactor
  26. }

  27. ()public override void ShowMessage
  28. }
  29. ;()ShowRedMessage
  30. {

  31. ()private void ShowRedMessage
  32. }
  33. ;()throw new NotImplementedException
  34. {
  35. {



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

پ.ن: نظر شخصی من این نیست که نباید از روالهای کنترلی استفاده شود، فقط باید جای درست انتخاب و استفاده شود. و به اصول موقع طراحی بیشتر دقت کنیم و در آخر اینکه این مثال بسیار ساده شده است و صرفا جهت نمایش عملکرد مورد انتظار ایجاد شده است و میشود در جاهای مناسب تری این مورد را بررسی کرد.



منبع:nikamooz