ما هر روز، هر لحظه در طول حرفه مهندسی خود، با مشکلات مختلفی با پیچیدگی ها و موقعیت های مختلف مواجه می شویم که به دلیل کمبود داده ها باید تصمیمی بگیریم یا آن را به تعویق بیندازیم. هر زمان که خدمات جدیدی می سازیم، زیرساخت می سازیم، یا حتی فرآیندهای توسعه را شکل می دهیم، دنیای عظیمی از چالش های مختلف را لمس می کنیم.
فهرست کردن همه مشکلات چالش برانگیز و شاید حتی غیرممکن است. تنها در صورتی با برخی از این مسائل مواجه خواهید شد که در یک جایگاه خاص کار کنید. از سوی دیگر، موارد بسیاری وجود دارد که همه ما باید نحوه حل آنها را بدانیم، زیرا برای ساختن سیستم های IT بسیار مهم هستند. با احتمال زیاد در تمامی پروژه ها با آنها مواجه خواهید شد.
در این مقاله تجربیات خود را در مورد برخی از مشکلاتی که در هنگام ایجاد برنامه های نرم افزاری با آن مواجه شده ام به اشتراک می گذارم.
اگر به ویکی پدیا نگاهی بیندازیم، تعریف زیر را خواهیم یافت
در توسعه نرم افزار جنبه گرا، نگرانی های مقطعی جنبه هایی از یک برنامه هستند که بر چندین ماژول تأثیر می گذارند، بدون اینکه امکان محصور شدن در هیچ یک از آنها وجود نداشته باشد. این نگرانیها اغلب نمیتوانند در طراحی و پیادهسازی از بقیه سیستم جدا شوند و میتوانند منجر به پراکندگی (تکثیر کد)، درهمتنیدگی (وابستگیهای قابل توجه بین سیستمها) یا هر دو شوند.
آن را تا حد زیادی توصیف می کند که چیست، اما من می خواهم آن را کمی بسط و ساده کنم:
یک نگرانی متقابل مفهوم یا جزء سیستم/سازمان است که بر بسیاری از بخشهای دیگر تأثیر میگذارد (یا «برش میدهد»).
بهترین نمونههای این نگرانیها عبارتند از معماری سیستم، ورود به سیستم، امنیت، مدیریت تراکنش، تله متری، طراحی پایگاه داده و بسیاری موارد دیگر. در ادامه این مقاله در مورد بسیاری از آنها توضیح خواهیم داد.
در سطح کد، نگرانیهای مقطعی اغلب با استفاده از تکنیکهایی مانند برنامهنویسی جنبهگرا (AOP) پیادهسازی میشوند، جایی که این نگرانیها به اجزای جداگانهای تبدیل میشوند که میتوانند در سراسر برنامه اعمال شوند. این امر منطق تجاری را از این نگرانیها جدا نگه میدارد و کد را خواناتر و قابل نگهداریتر میکند.
روشهای زیادی برای طبقهبندی جنبهها با تقسیمبندی آنها با ویژگیهای مختلف مانند محدوده، اندازه، عملکرد، اهمیت، هدف و موارد دیگر وجود دارد، اما در این مقاله، من قصد دارم از یک طبقهبندی دامنه ساده استفاده کنم. منظور من از این است که این جنبه خاص به کجا هدایت می شود، خواه کل سازمان باشد، یک سیستم خاص، یا یک عنصر خاص از آن سیستم.
بنابراین، من می خواهم جنبه ها را به ماکرو و میکرو تقسیم کنم.
منظور من از جنبه کلان عمدتاً ملاحظاتی است که ما برای کل سیستم دنبال می کنیم مانند معماری سیستم انتخابی و طراحی آن (یکپارچه، میکروسرویس، معماری سرویس گرا)، پشته فناوری، ساختار سازمانی و غیره. جنبه های کلان عمدتاً به استراتژیک و سطح بالا مربوط می شود. تصمیمات
در این بین، جنبه Micro به سطح کد و توسعه بسیار نزدیکتر است. به عنوان مثال، از کدام چارچوب برای تعامل با پایگاه داده، ساختار پروژه پوشه ها و کلاس ها، یا حتی الگوهای طراحی شی خاص استفاده می شود.
در حالی که این طبقهبندی ایدهآل نیست، به ساختار درک مشکلات احتمالی و اهمیت و تأثیر راهحلهایی که برای آنها اعمال میکنیم کمک میکند.
در این مقاله، تمرکز اصلی من بر روی جنبه های کلان خواهد بود.
وقتی تازه شروع به یادگیری معماری نرم افزار کردم، مقالات جالب زیادی در مورد قانون کانوی و تاثیر آن بر ساختار سازمانی خواندم. مخصوصا این یکی بنابراین، این قانون بیان می کند که
هر سازمانی که سیستمی را طراحی می کند (به طور کلی تعریف می شود) طرحی تولید می کند که ساختار آن کپی ساختار ارتباطی سازمان باشد.
من همیشه معتقد بودم که این مفهوم در واقع بسیار جهانی است و قانون طلایی را نشان می دهد.
سپس شروع به یادگیری رویکرد طراحی دامنه محور (DDD) اریک ایوانز برای سیستم های مدل سازی کردم. اریک ایوانز بر اهمیت شناسایی زمینه محدود تاکید می کند. این مفهوم شامل تقسیم یک مدل دامنه پیچیده به بخش های کوچکتر و قابل مدیریت تر است که هر کدام مجموعه محدودی از دانش خود را دارند. این رویکرد به ارتباطات تیمی مؤثر کمک می کند، زیرا نیاز به دانش گسترده از کل دامنه را کاهش می دهد و تغییر زمینه را به حداقل می رساند، بنابراین مکالمات را کارآمدتر می کند. تغییر متن بدترین و پرمصرفترین چیزی است که تاکنون وجود داشته است. حتی کامپیوترها هم با آن دست و پنجه نرم می کنند. اگرچه بعید است که به غیاب کامل تغییر زمینه دست یابیم، به نظر من این چیزی است که باید برای آن تلاش کنیم.
با بازگشت به قانون کانوی، چندین مشکل در آن پیدا کردم.
اولین مسئله ای که من با قانون کانوی مواجه شدم، که نشان می دهد طراحی سیستم ساختار سازمانی را آینه می کند، پتانسیل شکل گیری زمینه های محدود پیچیده و جامع است. این پیچیدگی زمانی به وجود می آید که ساختار سازمانی با مرزهای دامنه همسو نباشد و منجر به ایجاد زمینه های محدودی شود که به شدت به یکدیگر وابسته و مملو از اطلاعات هستند. این منجر به تغییر متن مکرر برای تیم توسعه می شود.
مسئله دیگر این است که اصطلاحات سازمانی به سطح کد نشت می کند. هنگامی که ساختارهای سازمانی تغییر می کند، نیاز به اصلاحات پایه کد و مصرف منابع ارزشمند دارد.
بنابراین، پیروی از مانور Inverse Conway به ساختن سیستم و سازمانی کمک میکند که معماری نرمافزار مورد نظر را تشویق کند. با این حال، قابل ذکر است که این رویکرد در معماری و سازههای از قبل شکلگرفته بهخوبی کار نمیکند، زیرا تغییرات در این مرحله طولانیتر است، اما در استارتآپها بهطور استثنایی عمل میکند، زیرا آنها به سرعت تغییراتی را ارائه میکنند.
این الگو یا «ضد الگو» باعث ایجاد یک سیستم بدون هیچ معماری می شود. هیچ قانون، هیچ مرزی، و هیچ استراتژی برای کنترل پیچیدگی رو به رشد اجتناب ناپذیر وجود ندارد. پیچیدگی سرسخت ترین دشمن در سفر ساختن سیستم های نرم افزاری است.
برای جلوگیری از ساخت چنین سیستمی، باید قوانین و محدودیت های خاصی را دنبال کنیم.
تعاریف بی شماری برای معماری نرم افزار وجود دارد. من بسیاری از آنها را دوست دارم زیرا جنبه های مختلفی از آن را پوشش می دهند. با این حال، برای اینکه بتوانیم در مورد معماری استدلال کنیم، طبیعتاً باید برخی از آنها را در ذهن خود شکل دهیم. و قابل ذکر است که این تعریف ممکن است متحول شود. بنابراین، حداقل در حال حاضر، شرح زیر را برای خودم دارم.
معماری نرم افزار درباره تصمیمات و انتخاب هایی است که هر روز می گیرید و بر سیستم ساخته شده تأثیر می گذارد.
برای تصمیم گیری که باید اصول و الگوهای "کیف" خود را برای حل مشکلات پیش آمده داشته باشید، همچنین ضروری است که بیان کنید که درک الزامات کلیدی برای ساختن آنچه یک کسب و کار به آن نیاز دارد است. با این حال، گاهی اوقات الزامات شفاف نیستند یا حتی تعریف نشده اند، در این مورد، بهتر است منتظر بمانید تا شفاف سازی بیشتری دریافت کنید یا به تجربه خود تکیه کنید و به شهود خود اعتماد کنید. اما به هر حال، اگر اصول و الگوهایی برای تکیه نداشته باشید، نمی توانید به درستی تصمیم بگیرید. اینجاست که من به تعریف سبک معماری نرم افزار می رسم.
سبک معماری نرم افزار مجموعه ای از اصول و الگوهایی است که نحوه ساخت نرم افزار را مشخص می کند.
بسیاری از سبکهای معماری مختلف بر روی جنبههای مختلف معماری برنامهریزیشده متمرکز شدهاند و بهکارگیری چندین آنها در یک زمان یک وضعیت عادی است.
به عنوان مثال، مانند:
معماری یکپارچه
طراحی دامنه محور
مبتنی بر مولفه
میکروسرویس ها
لوله و فیلتر
رویداد محور
میکروکرنل
خدمات محور
و غیره…
البته، آنها مزایا و معایب خود را دارند، اما مهمترین چیزی که من یاد گرفتم این است که معماری به تدریج در حالی که به مشکلات واقعی بستگی دارد، تکامل می یابد. شروع با معماری یکپارچه یک انتخاب عالی برای کاهش پیچیدگی های عملیاتی است، به احتمال زیاد این معماری حتی پس از رسیدن به مرحله تناسب محصول-بازار (PMI) ساخت محصول، با نیازهای شما مطابقت خواهد داشت. در مقیاس، ممکن است حرکت به سمت رویکرد رویداد محور و ریزخدمات برای دستیابی به استقرار مستقل، محیط پشته فناوری ناهمگن، و معماری کمتر جفت شده را در نظر بگیرید (و در عین حال به دلیل ماهیت رویکردهای رویداد محور و pub-sub اگر اینها پذیرفته می شوند). سادگی و کارایی به هم نزدیک هستند و تاثیر زیادی روی یکدیگر دارند. معمولاً معماریهای پیچیده بر سرعت توسعه ویژگیهای جدید تأثیر میگذارند، از ویژگیهای موجود پشتیبانی و حفظ میکنند و تکامل طبیعی سیستم را به چالش میکشند.
با این حال، سیستم های پیچیده اغلب به معماری پیچیده و جامع نیاز دارند که اجتناب ناپذیر است.
انصافاً، این یک موضوع بسیار گسترده است، و ایده های بسیار خوبی در مورد چگونگی ساختار و ساختن سیستم هایی برای تکامل طبیعی وجود دارد. بر اساس تجربیاتم، روش زیر را به کار بردم:
همچنین درک اعداد و معیارهایی مانند DAU (کاربران فعال روزانه)، MAU (کاربران فعال ماهانه)، RPC (درخواست در هر ثانیه) و TPC (تراکنش در هر ثانیه) حیاتی است، زیرا می تواند به شما در انتخاب کمک کند زیرا معماری برای 100 کاربر فعال و 100 میلیون کاربر فعال متفاوت هستند.
به عنوان نکته پایانی می گویم که معماری تاثیر بسزایی در موفقیت محصول دارد. معماری ضعیف طراحی شده برای محصولات در مقیاسبندی مورد نیاز است، که به احتمال زیاد منجر به شکست میشود، زیرا مشتریان منتظر نمیمانند تا زمانی که سیستم را مقیاسبندی میکنید، آنها یک رقیب را انتخاب میکنند، بنابراین ما باید از مقیاسبندی بالقوه جلوتر باشیم. اگرچه من اعتراف می کنم که گاهی اوقات نمی تواند یک رویکرد ناب باشد، ایده این است که یک سیستم مقیاس پذیر داشته باشیم اما قبلاً مقیاس نشده باشد. از سوی دیگر، داشتن یک سیستم بسیار پیچیده و در حال حاضر مقیاسپذیر بدون مشتری یا برنامهای برای به دست آوردن بسیاری از آنها، هزینهای برای کسبوکارتان ندارد.
انتخاب یک پشته فناوری نیز یک تصمیم در سطح کلان است زیرا بر استخدام، دیدگاههای تکامل طبیعی سیستم، مقیاسپذیری و عملکرد سیستم تأثیر میگذارد.
این لیستی از ملاحظات اساسی برای انتخاب یک پشته فناوری است:
چگونه داشتن چندین پشته فناوری می تواند بر رشد کسب و کار تأثیر بگذارد؟
از یک منظر، معرفی یک پشته بیشتر میتواند استخدام شما را افزایش دهد، اما از سوی دیگر، هزینههای نگهداری اضافی را به همراه دارد زیرا باید از هر دو پشته پشتیبانی کنید. بنابراین، همانطور که قبلاً گفتم، از دیدگاه من، تنها نیاز اضافی باید استدلالی برای ترکیب پشته های فناوری بیشتر باشد.
اما اصل انتخاب بهترین ابزار برای یک مشکل خاص چیست؟
گاهی اوقات چاره ای جز آوردن ابزارهای جدید برای حل یک مشکل خاص بر اساس همان ملاحظات ذکر شده ندارید، در چنین مواقعی انتخاب بهترین راه حل منطقی است.
ایجاد سیستم هایی بدون اتصال زیاد به یک فناوری خاص می تواند یک چالش باشد. با این حال، تلاش برای شرایطی که سیستم به شدت با فناوری مرتبط نباشد، مفید است و اگر فردا، یک چارچوب یا ابزار خاص آسیبپذیر یا حتی منسوخ شود، نمیمیرد.
ملاحظات مهم دیگر مربوط به وابستگی های نرم افزاری منبع باز و اختصاصی است. نرم افزار اختصاصی به شما انعطاف کمتری می دهد و امکان سفارشی شدن را به شما می دهد. با این حال، خطرناک ترین عامل قفل شدن فروشنده است، جایی که شما به محصولات، قیمت ها، شرایط و نقشه راه یک فروشنده وابسته می شوید. اگر فروشنده جهت خود را تغییر دهد، قیمت ها را افزایش دهد یا محصول را متوقف کند، می تواند خطرناک باشد. نرم افزار منبع باز این خطر را کاهش می دهد، زیرا یک نهاد واحد آن را کنترل نمی کند. حذف یک نقطه شکست در همه سطوح، کلید ایجاد سیستم های قابل اعتماد برای رشد است.
یک نقطه شکست واحد (SPOF) به هر بخشی از یک سیستم اطلاق میشود که در صورت از کار افتادن، باعث توقف عملکرد کل سیستم میشود. حذف SPOF ها در همه سطوح برای هر سیستمی که نیاز به دسترسی بالا دارد، بسیار مهم است. همه چیز، از جمله دانش، پرسنل، اجزای سیستم، ارائه دهندگان ابر و کابل های اینترنت، ممکن است با شکست مواجه شوند.
چندین تکنیک اساسی وجود دارد که میتوانیم برای حذف نقاط شکست به کار ببریم:
در این مقاله به چندین جنبه کلیدی ماکرو و نحوه برخورد با پیچیدگی آنها پرداختیم.
با تشکر از شما برای خواندن! دفعه بعد می بینمت!