خدا هیچ پدر و مادری رو محتاج فرزندشون نکنه!
در سلسله مراتب آموزشی هیچ وقت سخت ترین رو اول آموزش نمیدن. مسیر آموزش به نحوی چیده میشه که وقتی به غول مرحله ی آخر میرسین میبینین که چندان غول بزرگی نیست. DIP دقیقا به همین صورت هست.
در تعریف DIP دو نکته مهم گفته شده:
این دو نکته چیزی رو به یادتون نمیاره؟ استفاده از دو اصل قبل تر در SOLID یعنی LSP و OCP شما رو دقیقا به اصل DIP میرسونه و به این صورت شما وابستگی ها رو فقط به abstract ها مربوط کردین.
اگر شما LSP رو رعایت کنید برای پیاده سازی ها به راحتی از interface های مربوط به اون در کد استفاده میکنین و این interface ها هستن که ماژول ها رو به هم وابسته میکنن.
برای مثال یک برنامه ی ساده رو فرض کنین که دارای لایه های logic و data و ui است. میخواهیم نام یک مشتری رو در لایه ی ui نمایش بدیم. با توجه به DIP پیاده سازی ما به چه صورت باید باشه؟
public interface ICustomerDataAccess { string GetCustomerName(int id); } public class CustomerDataAccess: ICustomerDataAccess { public CustomerDataAccess() { } public string GetCustomerName(int id) { return "Dummy Customer Name" } } public class DataAccessFactory { public static ICustomerDataAccess GetCustomerDataAccessObj() { return new CustomerDataAccess(); } } public class CustomerBusinessLogic { ICustomerDataAccess _custDataAccess; public CustomerBusinessLogic() { _custDataAccess = DataAccessFactory.GetCustomerDataAccessObj(); } public string GetCustomerName(int id) { return _custDataAccess.GetCustomerName(id); } }
نکته1: در توضیح اصول قبلی SOLID گفته شد که Design pattern ها برای رعایت همین اصول به دنیا اومدن. درنتیجه خیلی مواقع نیاز نیست فکر کنیم که برای پیاده سازی هر کدوم از اصول SOLID باید چه کاری انجام بدیم و با مطالعه ی الگوی های طراحی موجود، به پاسخ مناسب میرسیم.
نکته2: کوچک ترین نکته ی پیاده سازی این اصل میتونه این باشه که interface ,abstract ها رو در جایی بزارین که برای ماژول سطح بالا و پایین قابل دسترس باشه.
نکته3: هیچوقت، هیچگاه، هرگز DIP رو با DI اشتباه نگیرین.