فرآیند طراحی استراتژیک

هر کسب و کاری برای موفقیت و ادامه حیات ناگزیر باید یک استراتژی منحصر به فرد برای خود داشته باشد. معمولا این استراتژی حول محور مزیت رقابتی کسب و کار شکل می گیرد و تمام قوانین و فرآیند های کسب و کار بر اساس همین استراتژی تعریف می شوند. اما موضوع به همینجا ختم نمی شود، استراتژی سازمان، تعداد پرسنل سازمان، تعداد واحدهای سازمان، محل استقرار واحد ها در سازمان، بودجه سالیانه، شرکای تجاری و هر آن چیزی را که در شکل گیری و پیشرفت مسیر کسب و کار نقش دارد را مشخص می کند.
استراتژی همه این موارد را با تمرکز بر مزیت های رقابتی کسب و کار به نحوی مشخص می کند که در نهایت منجر به موفقیت کسب و کار شود.

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

از طرفی طراحی سیستم نرم افزاری در کسب و کارهایی که دامنه بزرگ و پیچیده ای دارند، کار دشواری است. در این سیستم ها معمولا، با پیشرفت پروژه و اضافه شدن نیازمندی های جدید کسب و کار، به پیچیدگی طراحی اضافه می کند. غافل شدن از این پیچیدگی ها می تواند باعث شکست خوردن طراحی و پیاده سازی سیستم های نرم افزاری شود. معمولا دامنه کسب و کار های بزرگ به قدری پیچیده است که نمی توان به کل دامنه به چشم یک واحد نگاه کرد، پس، نیاز است که دامنه کسب و کار در دو بخش مفهوم و پیاده سازی به قسمت های کوچک تر تبدیل شود.

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

طراحی استراژیک در DDD شامل تکنیک های است که به معمار نرم افزار کمک می کنند تا بتواند دامنه کسب و کار را به دامنه های کوچک تر تبدیل کند و تمرکز طراحی را بر روی قسمت هایی بگذارد که مهم ترن قسمت های کسب و کار و استراتژی آن است و اهداف کسب و کار را شامل می شوند و راه کسب درآمد کسب و کار هستند.

انتخاب استراتژی های درست، به معمار نرم افزار کمک می کند مدل سازی بهینه ای از دامنه کسب و کار انجام دهد تا کسب و کار مورد نظر بتواند از طریق سیستم نرم افزاری به اهداف خود برسد.

در ادامه مراحل طراحی استراتژیک را در طراحی نرم افزار معرفی می کنیم.

اولین مرحله در طراحی استراتژیک شناسایی Subdomain ها است که به کمک آن می توانید فضای کسب و کار را به قسمت های کوچکتر تبدیل کنید که مهم ترین قسمت، Core Subdomain خواهد بود که بیشترین تلاش و هزینه برای این قسمت هزینه می شود، سپس یک سری قسمت ها Support Subdomain ها خواهند بود که برای عملکرد درست Core Subdomain وجودشان ضروری است ولی می توان در صورت وجود یک سری محدودیت های سازمان (مثل کمبود بودجه)، توسعه آنها را برونسپاری کرد. در نهایت باقی قسمت ها Generic Subdomain ها خواهند بود که قسمتی از کسب و کار را شامل می شوند که معمولا در بسیاری از کسب و کار ها وجود دارند و به سطحی از بلوغ رسیده اند که استاندارد های مشخصی برای آن ها وجود دارد و هزینه کردن برای توسعه آنها مقرون به صرفه نیست پس می توان به جای توسعه، از محصولات موجود در بازار استفاده کرد.

به فرض مثال در یک فروشگاه اینترنتی سیستم مدیریت سفارشات، Core Domain است. سیستم پشتیبانی مشتریان یک Support Domain و سیستم پرداخت اینترنتی یک Generic Domain.

اینکه کدام قسمت از کسب و کار Core Subdomain است یا Support Subdomain و یا Generic Subdomain کاملا توسط استراتژی سازمان مشخص می شود، چرا که، توسط استراتژی سازمان مشخص می شود که مزیت رقابتی کسب و کار کدام قسمت است، توسط استراتژی سازمان مشخص می شود که کدام قسمت ها از اهمیت کمتری برخوردار هستند اما وجودشان برای حیات مزیت رقابتی ضروری است و توسط همین استراتژی مشخص می شود کدام قسمت ها نیازی به تمرکز و پیدا کردن راه حل ندارند چون قبلا راه حل های آن ها کشف شده و می توان از راه حل های آماده استفاده کرد. و در نهایت توسط استراتژی سازمان، بودجه و هدف های پیش رو مشخص می شود و معمار نرم افزار با همه این موارد میتواند تعداد و نوع Subdomain ها را مشخص کند.

دومین مرحله در طراحی استراتژیک شناسایی Bounded Context ها است. برای شناخت بهتر کسب و کار به کمک شناسایی Subdomain ها فضای کسب و کار را به قسمت های کوچک تر تبدیل می کنیم و میزان هزینه و تلاش برای قسمت های مختلف را می شناسیم و تا مقدار زیادی از مسیر پیش روی توسعه نرم افزار را مشخص می کنیم، اما برای شناخت بهتر از هر Subdomain باید داخل هر کدام را نیز به بخش های مشخص تقسیم کنیم. معمولا سیاست میزان هزینه کرد برای هر Bounded Context داخل یک Subdomain یکسان است ولی می تواند نسبت به باقی Bounded Context های موجود در باقی Subdomain ها با توجه به Core بودن یا Support بودن آنها متفاوت باشد. مزیت دیگری که مشخص کردن Bounded Context ها دارد اینست که چند تیم به صورت همزمان و موازی می توانند بر روی Bounded Context های متفاوت کار کنند و آن Subdomain زودتر تکمیل شود.

در واقع Bounded Context ها واحد های مستقل با مرزهای مشخص در هر Subdomain هستند که قسمتی از وظایف مربوط به آن Subdomain را به عهده دارند. طراحی استراتژیک در اینجا مشخص می کند که وظایف هر Subdomain به چند دسته باید تقسیم شوند و مدل سازی آن وظایف به چه شکلی باید باشد و اینگونه هر دسته بندی به یک Bounded Context تبدیل می شود.

به فرض مثال در یک فروشگاه اینترنتی در Core Domain می توانیم سه Bounded Context برای ثبت سفارش، تحویل سفارش و وضعیت مالی سفارش داشته باشیم.

یک تصمیم استراتژی در مورد شناسایی Bounded Context ها در زمان شروع پروژه است. اگر در شروع نمی دانید باید چه تعداد Bounded Context داشته باشید، می توانید کل سیستم را به شکل یک Bounded Context واحد در نظر بگیرید و طراحی و توسعه را شروع کنید. سپس همچنان با پیشرفت پروژه دو اتفاق مهم رخ میدهد هم آن Bounded Context وسیع تر می شود و هم تیم توسعه بزرگتر می شود، که این دو اتفاق باعث کند شدن پیشرفت پروژه می شود، چرا که با بزرگ شدن Model و افزایش تعداد اعضای تیم دیگر همگام بودن اعضای تیم با یکدیگر و با توسعه پروژه کار دشواری است. در اینجا می توانید Bounded Context را بر اساس دسته بندی عملکرد های سیستم و بر اساس Model های موجود در پروژه به چند Bounded Context دیگر تقسیم کنید و همچنین چندین تیم توسعه تشکیل بدهید و هر کدام مسئول توسعه یک Bounded Context باشد.

سومین مرحله در طراحی استراتژیک مشخص کردن زبان مشترک داخل هر Bounded Context است. از آنجایی که قبل تر هم اشاره کردیم زبان مشترک و ادبیات مشخص می تواند تاثیر بسزایی در موفقیت یا شکست پروژه نرم افزاری داشته باشد، پس از روی اهمیت آن یکی از مراحل در طراحی استراتژیک مشخص کردن زبان مشترک و ادبیات داخل هر Bounded Context است.

چهارمین مرحله در طراحی استراتژیک مشخص کردن نوع ارتباط و نحوه تعامل بین Bounded Context ها است. این مرحله از مهم ترین مراحل در طراحی استراتژیک است و طراح نرم افزار با مشخص کردن Context Mapping یک نقشه کلی از ارتباطات و تعاملات بین Bounded Context های داخل هر Subdomain ارائه می کند. این راه حل یکی از راه حل های استراتژیکی است که به تیم ها کمک می کند با پروتکل های مشخص با یکدیگر ارتباط برقرار کنند و اینگونه با صرفه جویی در زمان، کمک می کند تا پروژه ها سریع تر و با چالش کم تر توسعه پیدا کنند. همچنین باعث می شود تیم ها از Bounded Context های دیگر و فضای کسب و کار شناخت بهتری داشته باشند که این خود به پیشرفت پروژه نرم افزاری کمک می کند.

پنجمین مرحله در طراحی استراتژیک تقطیر سازی دامنه (Distillation) است. تقطیر کردن به معنی استخراج کردن مواد با ارزش موجود در یک ماده است. این اصطلاح بیشتر در علم شیمی شناخته شده است، اما Eric Evans از آن برای بخش مهمی از طراحی استراتژیک در DDD استفاده کرده است. در رویکرد DDD تقطیر دامنه به معنی استخراج قسمت های مهم Core Domain برای قابل فهم تر شدن آن می باشد. قسمت های مهم Core Domain دقیقا همان قسمت هایی هستند که مزیت رقابتی کسب و کار را شامل می شوند و یا ارکان اصلی کسب و کار هستند. به عنوان مثال می توان به قابلیت هایی که برای مشتریان فراهم می کند، مشکلاتی که از مشتریان برطرف می کند و یا قوانین کسب و کار اشاره کرد.

در واقع در یک پروژه نرم افزاری شناسایی Sub Domain ها، شناسایی Bounded Context ها و مرز بین آنها و Model سازی کردن Domain بخشی از این تقطیر سازی است.

برای درک بهتر تقطیر سازی در DDD می توان فرآیند مدل سازی را در نظر گرفت. شما برای توسعه هر قسمت از نرم افزار نیاز به تحلیل آن قسمت در کسب و کار واقعی را دارید و پس از شناخت نیازمندی های آن قسمت از کسب و کار به همراه قوانینی که دارد و نحوه رفتار آن قسمت و تمام موارد مهم مربوط به آن قسمت یک مدل سازی انجام می دهید و سپس آن Model را در نرم افزار توسعه می دهید. پس می توانیم بگوییم شما قسمتی از دانش مربوط به یک کسب و کار را تقطیر کرده اید و حاصل این تقطیرسازی همان Model به دست آمده است. حال با پیشرفت پروژه و عمیق شدن افراد نسبت به دامنه این تقطیر سازی هم عمیق تر می شود و نتایج با ارزش تری نسبت به مراحل قبل تر به دست می آید. این نتایج با ارزش تر همان Model هایی هستند که تغییر می کنند و Refactor میشوند.

چرا تقطیر سازی در DDD اهمیت دارد؟ در سیستم های بزرگ دامنه کسب و کار و قوانین آن به قدری گسترده هستند که باعث پیچیده شدن Core Domain می شوند. حال اگر Core Domain پروژه نرم افزار شما پیچیده باشد، فهمیدن آن برای اعضای تیم سخت می شود، اگر اعضای تیم نتوانند Core Domain را به خوبی درک کنند در اعمال تغییرات نیز ناتوان خواهند بود و در نهایت هیچ تخمینی از هزینه و تاثیرات تغییرات نخواهند داشت. پس با تقطیر Core Domain قسمت های حیاتی آن را جدا می کنیم تا Core Domain قابل فهم تر برای ضینفعان پروژه داشته باشیم. نتیجه این کار شناخت راحت تر Core Domain توسط تمام اعضای تیم و به دنبال آن توسعه با سرعت بالاتر و دقت بیشتر است.

فرآیند مدل سازی

مدل سازی قلب تپنده رویکرد DDD است. مدل سازی به روش های مختلف و از زاویه دید های مختلف انجام می شود. فرآیند مدل سازی از تحلیل Domain آغاز می شود و هدف رویکرد DDD این است که Model تحلیل شده همسو با طراحی سیستم و کد باشد. در واقع طراحی یک انتزاع از Domain است و Model نمونه پیاده سازی شده این طراحی است پس اگر Model تحلیل شده با طراحی تفاوت داشته باشد بدین معنی است که انتزاع برگرفته شده از Domain به درستی پیاده سازی نشده است.

تعریف Subdomain

هر نرم افزاری بر اساس یک یا چند نیاز به وجود می آید و راه حلی برای برطرف کردن آن نیازها ارائه میکند. به فضایی که این نیازها را دربر می گیرد، فضای مساله گفته می شود. فضای مساله گاهی اوقات آن قدر بزرگ است و تعداد مشکلات و نیازهای زیادی را در خود می گجاند که باعث می شود به هم ریخته و پیچیده به نظر برسد. قطعا اگر شما با یک فضای پیچیده و به هم ریخته روبرو باشید و بخواهید با همان پیچیدگی و به هم ریختگی توسعه پروژه را شروع کنید و ادامه دهید نمی توانید نرم افزاری ارائه کنید که راه حل های مناسبی برای آن مشکلات و نیازها باشد.

برای سر و سامان دادن این فضای پر از پیچیدگی و به هم ریختگی باید نیازمندی ها و مشکلات موجود را دسته بندی کنید. نیازهایی که با یکدیگر ارتباط معنایی دارند را در یک دسته قرار دهید و برای هر دسته یک اسم انتخاب کنید که نشان دهنده دلیل انتخاب این دسته است. حال با نگاه کردن به فضای مساله اثری از به هم ریختگی وجود ندارد و تا حدی پیچیدگی کاهش یافته است. به این روش که باعث شفاف تر شدن فضای مساله می شود Subdomain Modeling و به هر کدام از آن دسته ها Subdomain گفته می شود.

از دیدگاه DDD سه نوع Subdomain داریم:

Core Subdomain: در این دسته مهم ترین نیازها قرار می گیرند. همان طور که در قسمت ابتدایی توضیح دادیم این دسته مهم ترین دسته است که دلیل اصلی وجود نرم افزار است. راه حل هایی که برای برطرف کردن نیازها و مشکلات موجود در این دسته ارائه میشوند در واقع همان مزیت رقابتی است که قرار است توسط این نرم افزار برای صاحب کسب و کار نسبت به رقبا ایجاد کند. بیشترین تلاش و بیشترین هزینه باید به این دسته اختصاص داده شود. به عبارت دیگر میتوان گفت این دسته محل درآمدزایی کسب و کار است.

برای مثال در یک فروشگاه اینترنتی که نیازهای زیادی را در حوزه فروش یک کسب و کار برطرف می کند، سیستم مدیریت سفارشات جز همین دسته حساب می شود. چرا که باید تعداد زیادی سفارش را در کمترین زمان ممکن با دقت بالا و عملکرد بهینه پردازش کند و این خود یک مزیت رقابتی نسبت به باقی رقبا و نقطه ورود پول به کسب و کار است.

Supporting Subdomain: قاعدتا نیازمندی های موجود در دسته Core Subdomain یک سری نیازمندی هایی دارند که کمتر شامل مزیت رقابتی می شوند، پس این نیازمندی ها در دسته Supporting Subdomain قرار میگیرند. وجود این نوع دسته بندی برای پاسخ دادن به نیازمندی های Core Subdomain ضروری است.
برای مثال در همان فروشگاه اینترنتی سیستم انبارداری یک Supporting Subdomain است که نیاز نگهداری محصولات را برای سیستم مدیریت سفارشات انجام می دهد.

Generic Subdomain: یک سری نیازمندی ها در هر کسب و کاری وجود دارند که در بین تمام کسب و کارها مشترک هستند و یک جزو نیازهای روزمره هر کسب و کاری هستند. به عبارت دیگر ارتباطی با حوزه فعالیت کسب و کار ندارند. معمولا راه حل های موجود در این دسته دارای استاندارد های مشخصی هستند که در بین اکثر کسب و کار ها یکسان می باشند. در واقع میتوان گفت نیازها و راه حل هایی که در این دسته قرار میگیرند ابزاری هستند در اختیار Core Domain و Supporting Subdomain برای آنکه بتوانند راه حل های خود را بهتر اجرا کنند.

برای مثال در همان فروشگاه اینترنتی سیستم ارسال ایمیل به مشتریان برای دلایل متفاوت یک نوع Generic Subdomain حساب می شود. چرا که زمان زیادی است که استاندارد مشخصی برای این موضوع معرفی شده و تمام کسب و کار ها از همین استاندارد استفاده می کنند.

سوال: از هر نوع Subdomain به چه تعداد می توانیم در پروژه داشته باشیم؟
معمولا در کسب و کارهای بزرگ دنیا بیش از یک منبع درآمدی وجود دارد و این منابع درآمدی ممکن است در فضای های جداگانه قرار دارند پس طبیعی است که در یک کسب و کار بزرگ چند Core Subdomain داشته باشیم، که هر کدام نیازهای هر کدام از منبع های درآمدی را شامل می شود.
تفاوتی ندارد که یک Core Subdomain داشته باشیم یا چند تا، در هر صورت تعداد Supporting Subdomain ها بیشتر از یک خواهد بود. چرا که معمولا نیازهای Core Subdomain زیاد هستند و تفاوت معنایی آنها باعث به وجود آمدن دسته های مختلف Supporting Subdomain ها می شود.
همانند Supporting Subdomain ها میتوان چندین Generic Subdomain در هر پروژه ای داشت تا نیازهای مختلف دسته های دیگر را برطرف کنند.

توسعه یا برونسپاری و یا استفاده از محصولات آماده؟
از آنجایی که برای Generic Subdomain ها راه حل ها با استانداردهای مشخص در قالب یک سری محصولات نرم افزاری ارائه شده است و برای آنکه بتوان تمرکز و تلاش تیم های توسعه را معطوف به Core Subdomain کرد، می توان به جای توسعه Generic Subdomain ها از همین محصولات آماده استفاده کرد.

در صورت محدود بودن منابع اعم از: نیروی انسانی، مالی و یا زمانی می توان در صورت موجود بودن محصولات آماده مربوط به Supporting Subdomain ها به جای توسعه از محصولات آماده استفاده کرد یا توسعه آن را برونسپاری کرد. در غیر اینصورت بهتر است توسعه، توسط تیم توسعه خود کسب و کار انجام شود.