کار بر روی نرم افزار Legacy: تکنیک بازنویسی، تجربه و درس

معرفی
تجربه اخیر من در زمینه مهندسی نرم افزار ساخت APIهای وب پشتیبان و ارتقاء سیستم های نرم افزار قدیمی بوده است. کار بر روی پروژههای قدیمی، من را در معرض مجموعههای مختلفی از تجربیات و درسها از دیدگاههای کد، جمعآوری و اصلاح نیازمندیها، تا الگوهای معماری گستردهتر قرار داد. در این مقاله من درس ها و تجربیات خود را در مورد الگوها، اصول و شیوه ها از دیدگاه کد و معماری در حین کار بر روی سیستم های نرم افزاری قدیمی به اشتراک خواهم گذاشت.
چه چیزی یک پروژه نرم افزاری را به میراث می گذارد؟
بهعنوان توسعهدهنده، میدانیم که سیستم نرمافزاری در اولین تلاش بینقص ظاهر نمیشود، و حتی اگر هم بینقص باشد، بهدلیل درخواستهای تغییر و مشکلات طراحی، پیوسته در حال تکامل است. این ثابت می کند که سیستم های نرم افزاری به دلیل قانون افزایش پیچیدگی و تغییرات مداوم که سال ها پیش توسط Manny Lehma و Les Belady بیان شده بود، نمی توانند یک بار ساخته شوند. حتی اگر نرم افزار ممکن است ناقص باشد، کد همچنان همانطور که انتظار می رود کار می کند و از این رو نرم افزار از نقطه نظر عملکردی خراب نمی شود. زمانی که مشکلات طراحی زودتر برطرف نشود، سازگاری نرم افزار با نیازهای در حال تغییر دشوار می شود. این نرم افزار زمانی که به دلیل هزینه تعمیر آن دست نخورده باقی بماند به یک سیستم قدیمی تبدیل می شود.
نرمافزار قدیمی برنامهای ارزشمند است که زمانی برای حل مشکلات تجاری ساخته شده بود و بدون نیاز به بازسازی مداوم، به دلیل قدیمی بودن زبانهای برنامهنویسی، روشهای توسعه، تغییرات مکرر در ابزارهای توسعه و غیره منسوخ میشود. با نرمافزار قدیمی، برنامه اصلی که طراحی شده بود. و مستقر شده از رانش طراحی رنج میبرد – پدیدهای که زمانی رخ میدهد که تیم توسعه به طور مداوم در تشخیص و سازگاری با تغییرات ناتوان است و باعث میشود مفاهیم موجود در حوزه نرمافزار و مفاهیم موجود در کد به آرامی از یکدیگر جدا شوند و ناهماهنگی ایجاد کنند. که در نهایت منجر به بدهی فنی می شود.
زیرا نرم افزارهای قدیمی برای کسب و کارهایی که با آن ها کار می کنیم ارزشمند است و همچنان در خدمت هدف هستند. به خاطر همین
آنها را نمی توان به طور کامل دور انداخت، بنابراین باید برای کاهش پیچیدگی و بهبود قابلیت نگهداری آنها دوباره مهندسی شوند.
طراحی و الگوهای معماری برای بازنویسی و بازسازی.
پروژههای نرمافزاری قدیمی که من با آنها کار کردهام، بیشتر برنامههای Backend هستند که با PHP نوشته شدهاند. آنها چیزهای مشترکی مانند تزریق وابستگی، پوشه های ویژگی، کنترلرها و غیره دارند. چنین پروژه هایی سال ها پیش بر اساس بهترین روش های آن زمان نوشته شده اند که در حال حاضر منسوخ شده اند. با تبدیل شدن پروژه به میراث، علائم خاصی ظاهر می شوند. در زیر برخی از علائم رایج در من وجود دارد:
- تست وجود ندارد یا از دست رفته است
- منسوخ یا بدون سند
- معماری پنهان
- کد بو می دهد
این علائم با تلاش برای درک نحوه عملکرد سیستم از طریق مهندسی معکوس آشکار می شوند. مهندسی معکوس با فعالیتهای زیادی مانند خواندن اسناد و کد منبع موجود، مصاحبه با کارشناسان دامنه، کاربران و توسعهدهندگان و بسیاری موارد دیگر همراه است. از طریق این فعالیتها، من توانستم مدل خود را در مورد نحوه عملکرد نرمافزار اصلاح کنم و در نتیجه بازسازی آن را آسانتر کنم.
اتخاذ الگوی خفه کننده
یک الگوی طراحی که امکان انتقال تدریجی سیستم به حالت مطلوب را فراهم میکند، اتخاذ شد زیرا ما نمیتوانستیم همه چیز را فوراً بسازیم. در اینجا الگوی خفه کننده به خوبی شناخته شده است. با جایگزینی تدریجی بخشهای خاصی از عملکرد با برنامهها و سرویسهای جدید، به انتقال تدریجی یک سیستم قدیمی کمک میکند. با این کار تمامی امکانات سیستم قدیمی جایگزین خواهد شد. این الگو توسط مارتین فاولر پیشنهاد شد.
بازنویسی من اتفاقاً بر روی یک چارچوب جدید PHP است. فریمورک Symfony توصیه شده ترین ابزاری بود که برای پورت کردن برنامه استفاده می شد.
با این رویکرد، من شروع به بازنویسی کنترلر جلو کردم تا از Symfony Request برای رسیدگی به درخواست برنامه استفاده کنم. در اینجا می توانید بیشتر بدانید که چگونه می توانید به این هدف برسید.
رسیدگی به ویژگی های موجود و درخواست های تغییر.
همانطور که من به تدریج ویژگی های موجود را منتقل می کنم یا الزامات تغییر جدید را به زیرساخت جدید پیاده می کنم، تصمیمات کلیدی باید اتخاذ شود که شامل موثرترین راه برای مدل سازی معماری جدید است تا مستقل از زیرساخت های پشتیبانی مانند چارچوب، ادغام های شخص ثالث باشد. و غیره. این کار قابلیت نگهداری و توسعه کد را آسان تر می کند. اینجاست که طراحی دامنه محور (DDD) به عنوان رویکردی برای توسعه نرم افزار مطرح می شود. اکثر تیمهای مهندسی اخیری که من با آنها کار کردهام، با تمرین فعالیتهایی مانند رویداد طوفان برای درک حوزه کسبوکار و اصول برای توسعه سیستمی که از چارچوبهای واسط جدا شده است، DDD را به خوبی پذیرفتهاند.
درک بهتر الزامات با رویداد طوفان
درک ویژگیهای برنامههای قدیمی موجود اولین مرحله در هر انتقال، بازسازی یا بازنویسی پروژه است. یک فعالیت کلیدی که ما اکثراً اجرا میکنیم جلسه طوفان رویداد برای مدلسازی دامنه پروژه است و از طریق آن میتوانیم رویدادهای مهم در سیستم، دستورات، موجودیتها را شناسایی کنیم و به احتمال زیاد پیادهسازی نرمافزار دامنه را منعکس کند، که هدف اصلی از DDD.
بهبود معماری سطح پایین (طراحی کد) با معماری شش ضلعی
در سطح پایین، همه این رویدادهای دامنه، دستورات، موجودیت ها و مجموعه ها اشیایی هستند که باید به صورت کد طراحی شوند. از آنجایی که ساختن یک سیستم جداشده هدف اصلی است، ما معماری شش ضلعی را اتخاذ می کنیم که به مدل سازی طراحی برنامه نرم افزاری در اطراف دامنه که از طریق فعالیت طوفان رویداد کاوش شده است کمک می کند. به عبارت دیگر، این راهی برای دفاع از منطق کسب و کار شما است که مدل دامنه شما را در برابر زیرساخت ها با لایه ها، پورت ها و آداپتورها تشکیل می دهد. همچنین، مدلهای دامنه عمدتاً به تکامل میرسند و از این رو عملیات نوشتن و خواندن در مدلها باید جدا شوند تا از دادههای ناسازگار محافظت شوند. اما اکثر سیستم های قدیمی هر دو عملیات را در یک مدل دارند. برای بهبود این امر، الگوی تفکیک مسئولیت فرمان و پرس و جو (CQRS) برای دستیابی به هدف ایجاد داده های سازگار با جداسازی عملیات نوشتن و خواندن در مدل ها اتخاذ شده است.
ابزارهای مفید
صرف نظر از اینکه کدها را چقدر خوب طراحی کردهایم، به ابزارهایی نیاز داریم که به اطمینان از رعایت استانداردهای خاص و مدیریت آسانتر در هنگام استقرار کمک کنند. در زیر برخی از ابزارهای مفید در اکوسیستم PHP که من از آنها استفاده کرده ام آورده شده است:
آزمایش کردن
یکی از نشانههای معمول سیستمهای قدیمی تست نبودن یا ناقص بودن آن است. و شروع به نوشتن تست برای این کدهای موجود که دشوار است زیرا چنین کدهایی بدون تعریف درز نوشته شده اند که تست را آسان تر می کند. یک راه عملی
برای اطمینان از اینکه ما در طول بازسازی مجدد چیزها را خراب نمی کنیم، نوشتن تست های یکپارچه سازی علیه سیستم تولید است. سپس تست های واحد را در حین بازسازی مجدد اضافه کنید.
درس ها
کار بر روی پروژه های قدیمی یک راهگشا بود. باید پایگاه کد موجود را کشف کرد: شیوهها، الگوها و اصول آنها و اینکه چگونه میتوان آنها را برای سیستمی بهتر با شیوهها، الگوها و اصول و ابزارهای مختلف مهندسی مجدد کرد. درس اصلی از این فعالیتها این است که احتمال زیادی وجود دارد که مشکلاتی که در پروژههای نرمافزاری با آن مواجه شدهاند، با آن مواجه شده، حل شده، به عنوان الگو یا رویکردی برای توسعه مستند شده و احتمالاً ابزارهایی برای آنها ایجاد شده است. بسیار ضروری است و این همیشه قسمت سرگرم کننده تیم است.