1. مقدمه:
اصل تفکیک روابط نام خود را با توجه به تصویر زیر به دست آورده است:
همانطور که تصویر بالا مشاهده میکنید، چندین User داریم که از توابع موجود در OPS استفاده میکنند. بیاید اینگونه فرض کنیم که User1 فقط از op1 و User2 فقط از op2 و نهایتا User3 فقط از op3 استفاده میکند.
حال فرض کنید که کلاس OPS با زبان جاوا یا C# توسعه داده شده باشد، در این شرایط User1 با اینکه هیچ استفاده ای از op2 و op3 ندارد ولی به طور ناخواسته به این دو تابع وابسته است. این وابستگی به این معنا است که در صورتی که سورس هر کدام از این دو تابع تغییر کند، با اینکه User1 استفادهای از آنها ندارد ولی مجدد Compile و Deploy میشود.
برای رفع این مشکل عملیات موجود در OPS را به چندین Interface به صورت شکل زیر تقسیم میکنیم.
مجدد یاداوری میکنم که فرض ما این است که این برنامه را با زبانهای استاتیک مثل جاوا یا سیشارپ توسعه دادهایم. حال وابستگیهای ما به این شکل است که User1 به U1Ops و op1 وابسته است و وابستگی به OPS ندارد. در این شرایط تغییرات OPS در متدهایی که برای User1 بیاهمیت است دیگر موجب Compile و Deploy برانامه User1 نمی شود.
2. زبان برنامه نویسی و ISP:
همانطور که در مثال بالا مشاهده کردید، وابستگی بین بخشهای مختلف به جز نحوه تعریف اجزا، به نوع زبان برنامهنویسی نیز کاملا مرتبط است. زبانهای برنامه نویس استاتیک مثل جاوا و سی شارپ و ... توسعه دهنده را مجبور میکنند که نوع مورد استفاده را با کمک Import یا using یا Include یا ... برای استفاده وارد برنامه خود کنند. با این روش تعیین وابستگی بین کدهای جاری و برنامههایی که مورد استفاده قرار میدهیم، وابستگی شدید سورس خواهیم داشت و با هر تغییر نیاز به recompile و redeploy داریم.
در زبانهای داینامیک مثل Ruby یا پایتون همچین وابستگیها و اجبارهایی بی معنی است. به جای این نوع وابستگی این زبانها وابستگیها را در زمان اجرا استنتاج میکنند. پس وابستگی بین سورسکدها که موجب اجبار به recompile یا redeploy شود وجود ندارد. یکی از دلایلی که زبانهای داینامیک میتوانند سیستمهای منعطف با چسبندگی کمتری ایجاد کنند همین موضوع است.
این موضوع ممکن است شما را به این فکر بیاندازد که ISP یک مشکل زبانی است تا مسئله معماری.
3. معماری و ISP:
اگر کمی به عقب برگردید و به نیرو محرکه اصلی ISP فکر کنید، میتوانید نگرانیها و نکات بیشتری را مشاهده کنید. وابستگی به ماژولی که امکاناتی بیشتر از آنچه که شما به آن نیاز دارید ارائه میدهد مخرب است. این که در سطح سورس کد نیاز به recompile و redeploy هستیم درست است. اما در سطح معماری نرمافزار مشکلات و نگرانیهای بزرگتری از این جنس وجود دارد.
به شکل پایین توجه کنید. فرض کنید معماری نرم افزار برای معماری سیستم S تمایل دارد از فریم ورک F استفاده کند که نویسند این فرمورک آنرا به دیتابیس D وابسته کرده است. بنا بر این S به F وابسته میشود که به D وابسته است.
حال فرض کنید D ویژگی دارد که F اصلا از آن استفاده نمیکند، در نتیجه این وجود یا عدم وجود این ویژگی برای S کاملا بی اهمیت است. حال فرض کنید آن ویژگی به گونهای تغییر کند که F مجبور به اصلاح خود شود و در نتیجه S نیز به اجبار باید برای ویژگی که برای او بی اهمیت بوده مجددا Deploy شود. اتفاق بدتر این است که خطا و شکست در ویژگی بی اهمیت D موجب خطا و شکست در F و در نتیجه S شود.
4. نتیجه گیری:
درسی که در این اصل وجود دارد این است که وابستگی به چیزی که از آن استفاده نمیکنیم ممکن است موجب خطایی شود که توقع آن را نداریم.
ما این ایده را در فصل سیزده و هنگام صحبت در مورد اصل استفاده مجدد مشترک دقیقتر بررسی خواهیم کرد.