Interface segregation Principle و dependency Inversion Principle

دوتا اصل اخر solid که تلاش برای استفاده درست از Interface ها دارد .Interface قابلیت های یکسان و پیاده سازی های متفاوت .هدف : اعمال قوانین و رفتار ( behavior ) به نرم افزار ‌که پیشنهاد شده برای تمام ، ( اصطلاحا module هامون ) قوانین داشته باشیم . Interface segregation Principle چهارمین اصل solid : اصل جداسازی Interface ها .در این اصل تاکید میشود که کلاس ها نباید متد هایی که نیاز ندارن را پیاده سازی کنند ( اصطلاحا ، چرا باید متد هایی را در اختیار کاربر ( developer ) قرار دهیم که هیچوقت قرار نیست برایشان کد تولید شود و فقط NotImplimentedException ، throw میکند ) مثال : فرض کنید یه روال کار ( workflow ) داریم ، که سه مرحله دارد .زمان پیاده سازی : تمام این سه مرحله را در یک interface قرار دهیم ( اصطلاحا : سه signature در یک interface ) و به اعضای هر مرحله ، در سه کلاس جدا پیاده سازی کنیم ‌( یعنی یک پدر و ۳ فرزند یا inheritance ) . یادآوری : وقتی یک کلاس از Interface ارث بری میکن موظف است تمام signature های آن را پیاده سازی کند )‌پس این عمل موجب میشود در هر پیاده سازی فقط یکی از مراحل ( method ها ) رفتار یا بدنه مربوط به آن مرحله را داشته باشه و دوتا متد دیگه NotImplimentedException پرتاپ کنند چون عملکرد انها مربوط به آن کلاس نیست .حالا فرض کنید ، اگر بعد ها یک مرحله دیگر به مراحلمان اضافه شود، چیکار باید بکنیم ؟؟؟ :)در این شرایط دو تا اصل solid را ( srp ، isp ) رعایت نمیکنیم .نتیجه : به همان اندازه که کاربرمان ( developer ) نیاز دارد ، متد در اختیارش قرار میدهیم ، نه بیشتر . Dependency Injection pattern یکی از راه های پیاده سازی اصل پنجم solid یعنی dependency Inversion Principle (معکوس سازی وابستگی ها ) استفاده از Dependency Injection pattern هست که ، از اصل delegation استفاده میکند .معکوس سازی وابستگی ها یعنی ماژول های سطح بالا ( high-level module ) ، نباید به ماژول های سطح پایین ( low-level module ) وابسته باشند و یا از آنها خبر داشته باشند ( اصطلاحا، لایه services نباید به لایه DAL وابسته باشه ). : Delegation یا DIهردو یک وظیفه دارند : وابستگی ها از کلاس ها خارج میکنند و به جای این که کلاس هایمان به پیاده سازی ( concrete ) وابسته شوند ، انهارا به یک سری قرار داد ( contract ) وابسته میکنند . تعریف delegation : تصور کنید ، یک سرویس داریم که یک سری وظایف دارد ، برای انجام وظایفش نیاز به یک سری اشیاع بیرون دارد ( مثل class ) که اگر خود سرویس ، مسئولیت تهیه این وابستگیها را داشته باشد ، کاملا به انها وابسته میشود ( مثل نمونه سازی از کلاس اشیا داخل سرویس ) .برای این که وابستگی ایجاد نشود ، میتوان مسئولیت ساخت نیازمندیها را به کلاس سرویس گیرنده ( استفاده کننده از سرویس ) داد و برایش قانون وضع کرد که اگر کسی خواست از کلاس سرویس دهنده استفاده کند ، باید خودش مسئولیت ساخت نیازمندیهایش را زمان نمونه سازی از سرویس‌دهنده ، برایش براورده کند .با این روش ما تمام وابستگی ها را از داخل سرویس دهنده خارج یا حذف میکنیم و مسئولیت آن را به سرویس گیرنده میدهیم ولی این روش مشکل ساز و سخت است . چطور از اصل DI یا delegation به درستی استفاده کنیم و مسئولیت تهیه نیازمندی هارا از سرویس گیرنده ، بگیریم و آن را به یک کلاس خارجی دیگر وابسته کنیم ( ارجاع بدیم جای دیگر ) . : DIContinerیه نوع service provider هست ( با رعایت اصل Delegation ) .تعریف : همه وابستگی ها را یکجا ( در یک subsystem ) تعريف میکنیم و همان subsystem مسئول مديريت همه وابستگی های نرم افزار ماست .برایش قانون وضع میکنیم :مثال قانون : هر کی از سرویس Isms خواست استفاده کند ، کلاس sms را بهش پاس بده و بعد ها اگر business سرویس sms مان تغییر کند ، فقط کافی اسم کلاس sms فعلی را به اسم کلاس جدید مثل NewSMS تغییر دهیم .بدون این که به کد هایمان دست بخورد ، رفتار جدید را جایگزین رفتار قبلی کردیم .هدف :جداسازی از وابستگی .منعطف بودن نرم افزار یعنی قسمتی از نرم افزار رو تغییر بدیم بدون این که به جای دیگر نرمافزار دست بخوره .قابلیت تست بالا .اگه ایراد تایپی داشتم یا ایراد توضیح داشتم خیلی خوشحال میشم بهم بگید تا اصلاح کنم .