‫یک مثال عملی از Decoupling

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

امروز موقعیت خوبی در یک برنامه ASP.NET پیش آمد که هم مزایای واقعی Decoupling (افتراق) را درک کنم و هم یک مثال ساده از آن اجرا کنم. یکی از امکاناتی که برای قسمت بندی بخش‌های مختلف برنامه و امکان Code Reuse در ASP.NET فراهم شده است امکان User Control است. برنامه‌نویس می‌تواند یک User Control نوشته و آن را در چند جای مختلف استفاده کند. یا حتی صرفاً از آن برای کاهش پیچیدگی استفاده کند. یکی از کارهای رایجی که خودم به شخصه در User Controlها انجام می‌دهم ارتباط با کنترل والد یا همان کنترلی است که کنترل مورد نظر من در آن قرار دارد. در موردی که من امروز با آن برخورد کردم User Control به Parent خود دسترسی پیدا کرده و از طریق FindControl یکی از دکمه‌های آن را Disable/Enable می‌کرد. این موضوع به غیر نازیبایی و ناخوانایی که ایجاد کرده بود باعث شده بود وقتی از این کنترل در جای دیگری استفاده می‌کردم خطا به وجود بیاید چون آن دکمه دیگر در اینجا وجود نداشت.

اعمال Decoupling (افتراق) در اینجا خیلی ساده بود. در User Control مورد بحث یک Event تعریف کردم و Disable/Enable کردن دکمه مورد نظر را به خود ماژول استفاده کننده سپردم. این ماژول فقط در Event تعریف شده مشترک می‌شد و Disable/Enable کردن دکمه را خودش انجام می‌داد. ماژول‌های دیگری هم که از User Control من استفاده می‌کردند هم صرفاً از همین Event استفاده می‌کنند. در واقع دیگر لازم نیست که User Control مورد نظر اطلاعی از وضعیت ماژول‌های والد خود داشته باشد و این یعنی Decoupling (افتراق).

Dependency Injection

همیشه وقتی سورس نرم‌افزارهای Open Source را بررسی می‌کردم به یک چیز بی‌معنی برمی‌خوردم: استفاده بی‌مورد از interface. مثلاً کلاسی را پیدا می‌کردم که پیاده‌سازی یک اینترفیس خاص بود در حالی که خود آن اینترفیس هم فقط در همان یک جا مورد استفاده قرار گرفته بود. تا جایی که من می‌دانستم استفاده از interface وقتی خوب است که بخواهیم چندین و چند کلاس داشته باشیم که بخواهیم آن یک interface خاص را پیاده‌سازی کرده باشند. چند وقت پیش بالاخره به صرافت افتادم و در StackOverflow پرسیدم که چرا این روزها استفاده از interface این قدر باب شده است.

جواب خیلی واضح و قابل قبول بود. چون با استفاده از interfaceها می‌توان مفاهیمی مثل Dependency Injection و Decoupling را در نرم‌افزار پیاده‌سازی کرد. استفاده از این مفاهیم یعنی کلاس‌ها و دیگر بخش‌های برنامه را طوری بنویسیم که در حد ممکن از دیگر بخش‌ها بی‌خبر بوده و در نتیجه به آن وابستگی نداشته باشند. برنامه‌هایی که به این روش نوشته می‌شوند مدیریت و نگهداری راحت‌تری دارند و خواناتر هستند. علاوه بر این‌ها تکنیک‌های جدیدی که در TDD و Mocking استفاده می‌شوند در برنامه‌هایی که به روش Dependency Injection نوشته شده‌اند خیلی کاراتر و راحت‌تر عمل می‌کنند.