اصل Dependency Inversion
تشریح اصل DI فراتر از حوصلهی این نوشته است و در اینجا در حد موضوع این نوشتار به آن میپردازیم. اصل Dependency Inversion را مرور کنیم. میگوید:
High-level modules should not depend on low-level modules. Both should depend on abstractions
این اصل یعنی چه؟ مفهوم «رانندگی اتومبیل» را به عنوان یک مفهوم انتزاعی سطح بالا در نظر بگیریم. شما به عنوان یک راننده پشت فرمان هر خودرویی که بنشینید بهتر است که درگیر پیچیدگیهای غیر ضروری مانند تعداد سیلندر و مشخصات فنی و ... نشوید و برای شما نباید فرق کند که مثلا سوخت ماشین بنزین است یا ماشین الکتریکی سوار شدهاید. مفهوم «رانندگی» نباید وابسته به مفاهیمی مانند موتور و کاربراتور و ... باشد. شما میخواهید ماشین را برانید و چیزی که برای شما اهمیت دارد چیزهایی مانند فرمان، تعداد دنده و مکان کلاج و پدال است. این مفاهیم مفاهیمی «هم سطح» با مفهوم «رانندگی» هستند. به این ترتیب میتوانید تجربه رانندگی را مستقلا حفظ کنید و این مفهوم سطح بالا (رانندگی) از یک ماشین به ماشین دیگر (low-level modules) دستخوش تغییر نشود. (فرض کنید که رانندگی هر ماشینی با ماشین دیگر کاملا متفاوت بود و برای یادگیری رانندگی هر ماشین باید آموزش جداگانهای میدیدید.) چیزی که اهمیت بیشتری دارد مفهوم سطح بالای رانندگی است و چیزهایی که تغییر میکند، مفاهیم سطح پایین تری مانند مدل ماشین و موتور و ... هستند.
برای اینکه اصل DI را به معماری هم تعمیم دهیم طراحی و وابستگی لایهها را به نحوی تعریف میکنیم که مفاهیم سطح بالا (High-level modules) وابستگی به مفاهیم سطح پایینتری مانند زیرساخت، سرویسهای بیرونی، واسط کاربر، ذخیرهسازها و ... نداشته باشد. چرا؟ مانند مثالی که زدم، اگر این سطوح انتزاع را رعایت نکنیم، مفهوم «رانندگی» با مفاهیم جزییتر وابستگی پیدا میکند و «پیچیدگی» غیر قابل کنترل میشود.
اصل DI و قدرت آن در کنترل پیچیدگی
در مواجهه با پیچیدگیها، برای اینکه بتوان پیچیدگی را به کنترل در بیاوریم ، عموما ۳ اقدام را به صورت هماهنگ انجام میدهیم.
1- Decomposition
2- Hierarchy
3- Abstraction
اگر
به تعریف اصل DI که در ابتدای این نوشته به آن اشاره شد توجه کنید،
میبینیم که این اصل به طور غیر مستقیم هم به Hierarchy (High/low level)
اشاره کرده، هم به Abstraction و هم به Decomposition (Not Depend…). لذا معماریهایی
که اصل DI در طراحی آنها به درستی مورد توجه قرار گرفته باشد به همین دلیل
در غلبه بر پیچیدگی موفقتر هستند که به طور ضمنی، طراحان و توسعه دهندگان را
به اقدامات سه گانهی Decomposition, Hierarchy, Abstraction سوق میدهند.
اصل DI و ارتباط آن با معماری نرم افزار
ابتدا توجه شما را به این نقل قول جلب میکنم:
If you apply the Dependency Inversion Principle to Layered Architecture, you end up with Ports and Adapters.-Mark Seemann
مشکلی در معماری موسوم به Layered Architecture وجود داشت این بود که Domain Logic به لایه Data Source وابسته بود. یعنی تجربه رانندگی، مثلا به تعداد سیلندرهای ماشین وابسته شده بود!
معماری های موسوم به Onion و Hexagonal یا همان (Ports & Adapters) جهت این وابستگی را اصلاح کردند. یعنی هر چه مربوط به Domain نبود را در بیرون از دایره (یا شش ضلعی یا ...) قرار دادند. دامین در مرکز قرار گرفت و لایههای دیگر (لایه های Mechanism و Utility) مجاز بودند که به دامین دسترسی داشته باشند (با واسطه) ولی خود دامین نمیتواند هیچ وابستگی به لایههای خارجی (بیرون از دایره وسطی) داشته باشد.
از جمله نتایج این طراحی این است که:
۱- قواعد کسب و کار و ... به طور کامل از جزییات دیگر منفک شود. بهبود از منظر Cohesion & Coupling
۲- مدل (Domain Model) خوانا و قابل فهم شود و توسعه آن آسانتر شود.
۳- طراحی Test Friendly شود.
۴- دامین مدل از دیتا سورسها مستقل شود. به این ترتیب امکان ایجاد تنوع در دیتا سورسها فراهم میشود. (یادمان بیاید که تغییر ظرفیت باک ماشین تجربه رانندگی را مختل نمیکند)
هر چند هر دو معماری Onion و Hexagonal در این وجوه با هم مشترکند اما جناب پالرمو (مطرح کننده معماری Onion) خلاقیت به خرج دادند و دو مفهوم، به آن اضافه کردند.
1- Domain Service
2- Application Service
به دلیل اینکه این مفاهیم نزدیک و هماهنگ با پترنهای مطرح در DDD هستند این سبک معماری را DDD Friendly به نظر میرسد. (مفهوم Application Service همان مفهوم Adapters است.)
ناگفته نماند که جناب پالرمو خودشان گفتهاند که معماری ابداعی ایشان، ایده تازهای نیست و آن را حاصل تفکرات پیشروانه کسانی مانند فاولر، کانینگهام، کنت بک و فدرز میداند:
I must stress again: I am not claiming any breakthroughs in technology or technique. I have learned from other industry thought leaders like Martin Fowler, Ward Cunningham, Kent Beck, Michael Feathers and others
برای مطالعه بیشتر درباره شباهتهای مفهومی معماریهای Hexagonal و Onion مطالعه لینک زیر پیشنهاد میشود.
http://blog.ploeh.dk/2013/12/03/layers-onions-ports-adapters-its-all-the-same/