قسمت اول : مقدمات
قسمت دوم : مبانی معماری (شما در حال خواندن این مقاله هستید)
قسمت سوم : نگاهی به معماری سنتی سه لایه
قسمت چهارم : اجزای Clean Architecture
قسمت پنجم : پیاده سازی بر اساس سرویس ها
قسمت ششم : پیاده سازی بر اساس UseCase ها
قسمت هفتم : آشنایی با CQRS
در بخش قبل مطالب اولیه بیان شد و بیشتر هدفم این بود که با انتقال دانسته های خودم به همراه جمع آوری اطلاعاتی که خوانده یا شنیدهام، نسبت به چیزی که قرار است نوشته شود مفروضات یکسانی پیدا کنیم.
بخش قبل بیشتر شبیه یک گپ دوستانه بود برای ایجاد یک فهم مشترک و در نهایت دو موضوع کد تمیز (clean code) و کد کثیف (messy code) دستاورد ما از آن نوشته شد. این مقاله در ادامه نوشته قبل به مفهوم معماری میپردازد تا در این زمینه هم به یک تفاهم برسیم.
بیشتر نوشته های این بخش بر پایه صحبت های مارتین فاولر (Martin Fowler) است که بنا به تجربه و مشاهداتم بسط و توضیح خواهم داد.
قبل از هر چیز یک سوال مهم وجود دارد. چرا مدیر فنی اکثر تیم های برنامه نویسی بدون در نظر گرفتن بزرگی پروژه (به لحاظ میزان هزینه انسانی و زمانی برای توسعه) و عمر توسعه آن(مقدار زمان پشتیبانی و اضافه کردن فیچرهای جدید)، اصرار بر پیاده سازی دقیق قواعد و قوانین یک معماری را دارد؟ اصلا این فرد یا هر فرد از آن تیم، تا به حال نرم افزاری با عمر ده یا بیست سال نوشته اند که بقیه را به پیاده سازی یک "معماری فضایی" مجبور میکنند؟
این نوع پیاده سازی کورکورانه، بیشتر از آنکه منجر به سادگی و سرعت و بهینه سازی باشد، سختی و مشکلاتی را به پروژه تحمیل خواهد کرد. اما راه حل چیست؟
ساده است. هر کدام از شما خوانندگان این مقاله، به هر حال درگیر حداقل یک پروژه هستید یا بوده اید. چه نوع معماری هایی را میشناسید؟ آنها را لیست کنید. حتا از تمپلیت ساده نرم افزاری که با آن کد مینویسید شروع کنید و هر مدل ساختاری را که میشناسید روی کاغذ بیاورد.
حالا فواید و معایب هر کدام را با توجه به پروژه ای که در نظر گرفتید، کنارش بنویسید. هنگام نوشتن، عمر نرم افزار، تعداد افرادی که روی آن مشغول بوند(هستند) و نحوه تست و توسعه آتی آن را در نظر بگیرد.
نتیجه مطمئنا این خواهد بود که اکثر پروژه ها خیلی ساده تر از آنچه فکر میکردید هستند و فقط با رعایت حداقل های اصول SOLID قابل پیاده سازی بودند.
نتیجه ای که گرفتیم به این معنی نیست که نباید از معماری استفاده کرد، بلکه نشان میدهد انتخاب درست برای هر پروژه صورت نگرفته است. ما نه تنها میتوانیم معماری های مختلف را انتخاب کنیم بلکه هر معماری پیاده سازی های متفاوتی هم دارد. پس دست ما بسته نیست که همیشه با یک فرمت خاص پروژه ها را شروع میکنیم!
میتوان گفت خیلی از اوقات، تحمیل یک معماری به یک پروژه، مزه ی بدی را به توسعه دهندگان آن خواهد چشاند چون همه نسبت به حدود توسعه پروژه آگاهند و سوال این است که چرا باید برای یک پروژه کم عمر و کم حجم، اینهمه پیچیدگی را تحمل کنیم وقتی خیلی ساده تر قابل انجام و توسعه است؟
اصولا معماری چیست؟ مفهوم معماری از ساخت و ساز قرض گرفته شده ولی در حوزه نرم افزار باید با احتیاط آن را معنا کرد. معنی رسمی معماری نرم افزار را در اینترنت سرچ کنید؛ در این مقاله قصد بحث در مورد آن را نداریم.
اگر به داخل یک تیم نرم افزاری برویم و با متخصصان برنامه نویس پروژه یعنی کسانی که با پروژه آشنا هستند و آن را توسعه میدهند صحبت کنیم همه یک درک مشترک و معمول از نحوه کارکرد اجزای سیستمی که نوشته اند دارند. این درک مشترک را میتوان به عنوان معماری آن نرم افزار در نظر گرفت. میتوان گفت معماری یک موضوع اجتماعی است؛ یعنی یک موضوع بین انسانی در رابطه با برداشت مشترک از کارکرد یک نرم افزار. هر چیزی مثل دیاگرام ها و داکیومنت هایی که در مورد معماری صحبت میکنند در حقیقت یک نمایش از آن درک مشترک هستند.
تمام کاری که ما باید با یک پروژه نرم افزاری «مخصوصا از نوع بزرگ و با عمر زیاد» آن انجام دهیم این است که مطمئن شویم با بقیه افرادی که عضو تیم هستند به یک فهم و درک مشترکِ خوب رسیده ایم.
از طرفی معماری وابسته به تصمیماتی است که خیلی زودتر از شروع پروژه باید اتخاذ شوند، یعنی چیزهایی که حین توسعه پروژه کمتر قابل تغییر هستند. مثل انتخاب زبان برنامه نویسی.
به کمک این "فهم مشترک" و "پارامترهای انتخابی غیر قابل تغییر" باید بتوانیم نکات کلیدی پروژه را در حین انجام پروژه در نظر داشته باشیم. در هر لحظه باید بدانیم که چه نکاتی مهم است و چه کارهای مهمی باید انجام دهیم.
چرا معماری نیاز است؟
در نرم افزار کیفیت را میتوان به دو بخشِ سمت کاربر و سمت کد تقسیم کرد. بخش کاربر آن چیزی است که استفاده کننده ها میبینند؛ طبیعیست در نگاه اول یک ساختار استاندارد و درست در سمت کد ها «ظاهرا» ربطی به این بخش ندارد.
این دو بخش را میتوان External Quality (کیفیت بخش کاربر) و Internal Quality(کیفیت سمت توسعه دهنده) نامید. معماری در مورد بخش Internal صحبت میکند.
در بخش Internal باید با توجه به ویژگی های پروژه یک نگاه طولانی مدت به نرم افزار داشت. وقتی به معماری و استاندارد ها در پروژه توجه نکنید، در طول زمان، هر وقت بخواهید یک امکان و فیچر جدید به نرم افزار اضافه کنید سخت و سخت تر میشود تا جایی که این توسعه ممکن نخواهد بود، تنها دلیل، ویژگی های کدیست که پیش از این نوشتیم و باعث میشود کار با آن سخت و زمانبر شود و میزان خطاها افزایش یابد.
اما اگر یک معماری خوب و تمیز داشته باشید و مرتبا کد خود را refactor کنید تجربه متفاوتی خواهید داشت.
در حالت Good Design به دلیل ساختار درست و ماژولار و کامپوننت های جدا، ایجاد فیچرهای جدید ساده تر خواهد بود و نیازی به دستکاری ساختار یا کامپوننت های دیگر نیست.(مثال ماکارونی و لازانیا را به یاد آورید) همچنین تغییر و بهینه سازی در حین توسعه ساده تر خواهد بود و دقیقا میدانیم چه چیزی را در کجا باید اصلاح یا بهینه کنیم.
برگردیم به بحث کیفیت، عدم استفاده از معماری درست مستقیما روی کیفیت Internal یعنی کدهای ما اثر میگذارد ولی مشکلاتی که عدم استفاده از یک معماری درست در سمت External ایجاد میکند قابل چشم پوشی نیست. فیچرهای جدید دیر اضافه میشوند، به روزرسانی ها کند و پرباگ خواهند بود و ... . در حقیقت ارزش رقابتی ما در بازار کم میشود و به مرور مشتریان خود را از دست خواهیم داد.
این توضیحات نشان میدهد چرا به لحاظ اقتصادی نیز، معماری نرم افزار اهمیت دارد. در مقاله قبل تا این حد به عمق موضوع نپرداختیم و معماری را صرفا یک موضوع درونی توصیف کردیم ولی حالا میبینیم که معماری(به معنایی که در ابتدای این مقاله توضیح دادیم) موضوع بسیار مهمی است.
هنگامی که به پروژه نرم افزاری خود فکر میکنید به موضوعات شبیه موارد زیر فکر کنید :
معماری سنتی سه لایه به ما کمک میکند که بسیاری از این خواسته ها در آینده با کمترین تغییر در کد حل شود.
در مقاله بعدی با این معماری بیشتر آشنا خواهیم شد.