در اینجا 5 مورد از مهمترین اشتباهات که غالبا توسعهدهندگان backend مرتکب میشوند را بیان میکنیم بعد از خواندن این مقاله، در صورتی که قبلا این اشتباهات برای شما اتفاق افتاده است، باید بدانید چگونه از بروز یک اشتباه خاص وعواقب آن جلوگیری کرده و چطور با آن مقابله کنید.
1. بدهی فنی (technical debt) بیش از حد، مهندسی بیش از حد/بهینهسازی بیش از حد
مسأله:
ما این اشتباه توسعه backend را به عنوان اولین مورد ذکر کردهایم زیرا به نظر میرسد بسیار شایع است و اگر زود رفع نشود، بعدا به سختی رفع خواهد شد، حتی گاهی اوقات نیاز به بازنویسی قسمت عظیمی از پروژه میشود. استفاده بیش از حد از بدهی فنی به معنی استفاده از عملکردهای بد مثل شکستن قوانین SOLID و DRY، توابع و متدهای خیلی طولانی، تعداد تو رفتگیهای بسیار زیاد، عدم انجام تست (در موارد بعدی توضیح داده میشود)، از دست دادن مستندات، نامگذاری ضعیف متغیرها، نامگذاری ضعیف پیامهای کامیتشده، عدم توجه کافی به عملکردها و غیره میباشد. همچنین میتواند به معنی معماری بدی باشد که معمولا حتی اوضاع را وخیمتر میکند. در اصل اگر کد کثیف باشد، میتوانید آن را ریفکتور کنید اما اگر کل سیستم بد طراحی شده باشد، اصلاح آن بسیار سختتر میشود.
مهندسی بیش از حد (over-engineering) زمانی اتفاق میافتد که توسعهدهندگان backend در یک لحظه معین از یک الگوی خیلی پیشرفته استفاده میکنند، در حالی که یک راهحل بسیار سادهتر میتواند به خوبی کار کند. بهینهسازی بیش از حد (over-optimization) یعنی مراقبت بیش از حد از یک عملکرد در جایی که واقعا مهم نیست، مثلا کوتاه کردن یک پروسیجر خاص از 0.1 ثانیه به 0.01 ثانیه، در حالی که یک پروسیجر دیگر، که یک تنگنا محسوب میشود، حدود 15 ثانیه طول میکشد.
عواقب:
در طولانی مدت، هر یک از این موارد منجر به هدر رفتن زمان توسعه میشود زیرا توسعه هر ویژگی جدید به طور کلی سختتر و در بعضی مواقع نزدیک به غیر ممکن میشود. گاهی اوقات زمان پیادهسازی هر ویژگی جدید افزایش مییابد زیرا نیاز به تست تمام مسیرهای ممکن یا همه شرایط موجود در تولید کد برای آپدیت و ترکیب ویژگیهای قدیمی با ویژگیهای جدید است. بنابراین نگه داشتن کد امری دشوار می شود.
هم بدهی فنی و هم مهندسی بیش از حد نگهداری کد را دشوار میسازند. بهینهسازی بیش از حد ممکن است علتی برای ایجاد مهندسی بیش از حد شود، که اغلب این مورد وجود دارد.
پیشگیری:
هنگام توسعه یک ویژگی خاص، توسعهدهندگان backend باید ویژگیهای آتی را در نظر بگیرند تا بدانند آیا ارزش مهندسی بیش از حد یا بهینهسازی بیش از حد را دارد. ما همچنین باید طول عمر عملکردی (چه مدت این ویژگی در تولید استفاده خواهد شد) و طول عمر تکنیکی (چه مدت ممکن است این ویژگی با تکنولوژیهای فعلی استفاده شود) را در نظر بگیریم تا بدانیم بدهی فنی در یک لحظه معین چقدر مهم است. بررسی هر ویژگی و هر رفع باگ (در موارد بعد توضیح داده میشود) مهم است.
راهکار:
وقتی میفهمیم بدهی فنی یا مهندسی بیش از حد نگهداری را بسیار دشوار میسازند باید آن را با روشهای مناسب و سادهتر ریفکتور کنیم. با این حال بهینهسازی بیش از حد، اگر با مهندسی بیش از حد مرتبط نباشد، نباید در راهکارها قرار گیرد زیرا خوب است که اجرای کد سریعتر باشد. ما قبلا زمان را صرف بهینهسازی بیش از حد هدر دادهایم، که این یک مشکل است، اما نمیتوانیم زمان را برگردانیم.
2. عدم انجام تست یا ننوشتن تست برای هر بخش از هرم برنامه
مسأله:
عدم انجام تست به این معناست که برای یک سناریوی مشخص تست نوشته نشده باشد یا هیچ تستی برای یک ویژگی خاص وجود نداشته باشد. عدم تست درهر بخش از هرم تولید برنامه یعنی حداقل در یک سطح از این هرم تست را ننوشته باشیم.
عواقب:
این امر منجر به تولید کدی میشود که نگهداری آن برای توسعهدهندگان backend دشوار است زیرا به مرور زمان آنها از هر تغییری میترسند، که باعث افزایش تعداد باگها میشود، با این حال یادمان باشد که تست کامل غیرممکن است.
پیشگیری:
نوشتن تمام تستها در هر سطح به همراه ویژگیهای جدید و تستهای رگرسیون به همراه رفع باگ به شما کمک میکند. تستها باید در برنامه روزمره قرار بگیرند. این کار ممکن است توسط هر توسعهدهنده backend به صورت جداگانه با استفاده از TDD (توسعه تست محور) و تحلیل کدهای استاتیک و بررسی پوشش کد انجام شود. یکی دیگر از رویکردهای نوشتن تست مربوط به کار گروهی است. گاهی اوقات ممکن است یک نفر مخالف نوشتن تست باشد. این مخالف میتواند توسعه دهنده تازهکار backend باشد که هیچ تجربهای در نوشتن تست ندارد یا صاحب محصول باشد که میخواهد همه چیز با بیشترین سرعت ممکن اجرا شود. بنابراین ضروری است که برای آنها توضیح دهیم که چرا تستها اینقدر مهم هستند. دلایل اصلی عبارتند از: عملکرد بالا در طولانی مدت، حتی گاهی اوقات در صورتی که یک ویژگی خاص پیچیده باشد عملکرد بالا در کوتاه مدت را نیز به همراه دارد، باگهای کمتر، و در نهایت طراحی معماری بهتر.
راهکار:
به طور کلی برای انجام بخشهای مختلف باید از زیر مجموعه "پیشگیری" برای اصلاح کارها استفاده کنید، اما شما باید تجزیه و تحلیل کنید که کدام ویژگیها و سناریوها برای اعمال تست بر روی آنها به ترتیب ضروریتر هستند.
3. عدم بررسی کد (code review) یا تحلیل کدهای استاتیک
مسأله:
عدم بررسی کد به معنای ارسال کد به شاخه (branch) پیشفرض بدون اینکه حداقل یک توسعهدهنده backend دیگری آن کد را به صورت خط به خط بررسی کند میباشد. عدم تحلیل کد استاتیک به معنای ارسال کد به شاخه پیشفرض بدون تحلیل آن توسط ابزاری مانند ESLint برای JavaScript یا TSLint برای TypeScript است.
عواقب:
عواقب احتمالی، شیوههای بد یا استایل کد متناقض است که نگهداری کد را دشوارتر و آسیبپذیرتر میسازد و باعث عدم مدیریت موارد پیشرفته میشود.
پیش گیری:
برای پیشگیری از این اتفاق، هر PR/MR را قبل از ادغام بررسی کنید (و البته این موارد را به صورت مستقیم برای هر یک از شاخههای محفوظ که ممکن است در GitHub یا GitLab اجرا شود، ارسال نکنید) و از ادغام مداوم (continuous integration) برای اجرای تحلیل کد استاتیک پس از ارسال هر کامیت استفاده کنید.
راهکار:
برای رفع این اشتباه توسعه backend، ما باید مراحلی مثل شروع بررسی کد، پیکربندی تحلیل کد استاتیک و بررسی کد که قبلا در شاخه پیشفرض بوده است اما هنوز بررسی نشده است را در نظر بگیریم.
برای بررسی کد میتوانید یا یک توسعهدهنده frontend از همان پروژه یا یک توسعه دهنده backend از یک پروژه دیگر را بگذارید تا کد شما را بررسی کند یا چه بهتر که هر دو این کار را انجام دهند. اولی دارای یک حوزه دانش است و دومی دانش backend را دارد.
یا میتوانید با توجه به موقعیت جغرافیایی افراد تیم آنها را تقسیمبندی کنید تا هر زیر مجموعه بررسی کد خود را انجام دهد.
4. استفاده از بسیاری از تکنولوژیها، کتابخانهها یا رویکردها برای کارهای مشابه
مسأله:
به طور کلی، توسعهدهندگان backend باید از تکنولوژیهای مشابه (زبان برنامهنویسی یا فریمروک یا کتابخانه یا DBMS یا یک API خارجی) و الگوهای مشابه برای حل یک مسأله خاص استفاده کنند. مثالهای این موارد عبارتند از جاوااسکریپت برای برنامهنویسی سطح بالا، Moment.js برای عملیات تاریخ/زمان، MongoDB برای ذخیره سازی اسناد، factory function برای ایجاد یک آبجکت.
البته استفاده از پایتون به جای جاوااسکریپت، Day.js به جای Moment.js، CouchDB به جای MongoDB یا کلاس به جای factory function خوب است، اما شما باید تصمیم بگیرید که برای کل پروژه از کدام مورد استفاده کنید. یک اکستنشن میتواند با یک تکنولوژی جدید در برخی بخشها استفاده شود، اما بعدا شما باید از این تکنولوژی در کل پروژه خود استفاده کنید.
عواقب:
داشتن رویکردها یا تکنولوژیهای متناقض، نگهداری کد را دشوارتر میسازد زیرا به دانش بسیار بیشتری نیاز دارد. به دلیل تعداد وابستگیهای بیشتر، ریسک بیشتری برای ایجاد باگها و آسیبپذیری وجود دارد، و از آنجایی که وابستگیهای بیشتری باید نصب شوند، نصب کندتر صورت میگیرد.
از تکنولوژیها و الگوهای مشابه برای یک مسأله خاص و بررسی کد (مورد قبلی) استفاده کنید.
راهکار:
ما باید تصمیم بگیریم کدام فناوری یا رویکرد برای پروژه ما بهترین است و بقیه کد را ریفکتور میکنیم تا همیشه از همان تکنولوژی یا رویکرد استفاده کنیم.
5. عدم گرفتن نسخه پشتیبان (backup) از دیتابیس
مسأله:
ممکن است گاهی اوقات دیتابیس به طور کامل یا جزئی حذف شود یا برخی دادههای نامعتبر به دلیل وجود یک باگ یا برخی عملیات دستی وارد آن شوند. دادههای تولید شده معمولا با ارزشتر از کد ما هستند زیرا کد میتواند نتیجه کار دهها توسعهدهنده backend باشد در حالی که دادههای تولید شده میتواند کار هزاران یا حتی میلیونها کاربر برنامه باشد. علاوه بر این، کد را میتوان با برنامه دیگر جایگزین کرد در حالی که بازیابی دیتابیس بدون نسخه پشتیبان ممکن است غیرممکن باشد.
عواقب:
کاربران سیستم ما ممکن است نتیجه کار خود را از دست بدهند. برخلاف سایر موارد گفته شده، در صورت از بین رفتن دادههای تولید شده ما احتمالا مجبوریم خسارت پرداخت کنیم.
پیشگیری:
بکآپ گیری خودکار را پیکربندی کنید، مثلا MongoDB Atlas یک پشتیبانگیری خودکار متناوب را بدون هیچ تنظیمات خاصی ارائه میدهد.
راهکار:
اگر پشتبانگیری خودکار را قبلا انجام ندادهاید، آن را کانفیگ کنید. اگر دیتابیس بدون پشتیبانگیری از بین رفته باشد، خیلی دیر شده است، اما اگر خوششانس باشید، ممکن است بتوانید بخشی از دادهها را از لاگها (در بخش بعدی توضیح داده میشود) بازیابی کنید یا از همتیمیهای خود بپرسید ببینید آیا آنها نسخه پشتیبان دستی تهیه کردهاند؟
طراحی اپلیکیشن اندروید | طراحی وب سایت | شرکت ایده پردازان پاراکس