۱۰ مورد از چیزهایی که هر توسعه دهنده باید یاد بگیرد

ترجمه و تالیف : علیرضا داداشی
تاریخ انتشار : 28 مهر 99
خواندن در 7 دقیقه
دسته بندی ها : برنامه نویسی

من یک توسعه دهنده پایتون پلاس و Go هستم و در طی چند سال گذشته نیز برنامه‌های مربوط به مقیاس جهانی را اجرا می‌کنم. من به همراه تیم خود روزانه حدود دو میلیون مشتری را مدیریت می‌کنیم، انجام چنین کاری اصلا آسان نیست. قصد دارم چند نکته را که حاصل سال‌ها تجربه‌ی شخصی است با شما به اشتراک بگذارم.

امنیت باید همیشه در اولویت باشد

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

هر برنامه متفاوت است و به طبع نیازهای مختلفی را داراست. مطابق با نیازهای برنامه انتخاب کنید نه براساس فشارهای سیاسی یا محبوبیت در بازار.

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

ما با شرکت‌هایی مثل Canonical مواجه می‌شویم که Kubernetes را به دستگاه‌های بسیاری پیشنهاد داده‌اند. جف گلدبلوم گفته است:«دانشمندان شما آنقدر به توانایی انجام یک کار دقت کردند که اصلا وقت نکرد‌ه‌اند به این فکر کنند که آیا باید اصلا از آن استفاده کنند یا نه.»

احتمالاً به انجام میکروسرویس احتیاج ندارید

میکروسرویس‌ها جذاب و جالب هستند. اینکه بتوانید بطور مستقل موارد متنوعی از آیتم‌ها را در برنامه خود تنظیم کنید بسیار هیجان‌انگیز است. کار کردن بر روی این پایگاه کد خاص می‌تواند آموزنده باشد. بگذارید با خودمان صادق باشیم، احتمالاً نیازی به میکروسرویس نخواهید داشت. دلایلی مانند توانایی جداسازی فیچر X از فیچر Y یک کد، جلوگیری از ورود کدهای نادرست به بخش‌های دیگر برنامه و به حداقل رساندن شعاع انفجاری مخرب برای برنامه جزو مواردی نیستند که بتوانند شما را به سمت استفاده از میکروسرویس‌ها سوق دهند. اگر بخواهیم به ترتیب بگوییم آن‌ها نشانه‌هایی از روش‌های نامناسب در توسعه، نبود استانداردهای دقیق در بررسی کد و عدم وجود کنترل‌های امنیتی مناسب می‌باشند.

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

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

الف) باید موارد دلخواه را به آن اضافه و تنظیم کنید. حال حضور اولیه شما ۵ برابر شده است.

ب) یا از حضور فعلی خود استفاده می‌کنید. اینگونه هزینه‌های عملیاتی بیشتری برای مدیریت شدن به وجود خواهند آمد.

برای توسعه یک محیط استاندارد داشته باشید

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

 به عنوان مثال همکار شما در حال کدنویسی با Go 1.11 است اما شما مشغول تشخیص دادن باگ‌ها با Go 1.12 هستید. این می‌تواند بسیار زجرآور و ناراحت‌کننده باشد. اینکه چه زمانی نسخه‌های خود را بروزرسانی کنید می‌تواند دشوار باشد، اما اگر کارهای خود را به درستی انجام دهید همه چیز وفق مراد شما پیش خواهد رفت.

پیکربندی دشوارتر از آن چیزی است که به نظر می‌رسد؛ مطابق با آن برنامه‌ریزی کنید

 برخلاف آنچه که برخی از وبسایت‌های معروف می‌گویند، پیکربندی کمی پیچیده‌تر از «قرار دادن همه چیز در متغیرهای محیط» است. به نظر من برای پیکربندی کردن یک برنامه نباید کمتر از ۴ راه وجود داشته باشد: پیش فرض‌های درون کد، فایل پیکربندی محلی، فلگ‌های خط فرمان، متغیرهای محیط و منبع پیکربندی ریموت.

 من پیکربندی ریموت را اختیاری در نظر می‌گیرم؛ با این حال ۴ مورد دیگر لازم و ضروری هستند. به منظور توسعه،  قرار دادن ۲۷ پیکر مختلف در متغیرهای محیط برای اجرای محلی برنامه می‌تواند دلسردکننده باشد. شاید شما به اتوماسیون و Makefile بهتری نیاز داشته باشید؟ فراهم کردن روشی برای داشتن یک منبع پیکربندی محلی مثل "application.yaml" این امکان را به شما می‌دهد تا پیکربندی پیش فرض "dev" را اعمال کنید.

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

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

در صورت نیاز از پکیج‌ها استفاده کنید

همه‌ی ما در مورد "left-pad" می‌دانیم. حذف شدن یک پکیج ۱۱ خط NPM از ریپازیتوری چگونه می‌تواند همه چیز را در اینترنت خراب کند؟ پکیج‌ها باید در مواقع لزوم (مثلا یک SDK) مورد استفاده قرار گیرند. می‌توانید از آن در یک انتزاع مجموعه‌ای در کتابخانه‌ها استفاده کنید. به همین دلیل است که مردم دوست دارند به جای urllib از پایتون استفاده کنند. از کاربردهای دیگر آن می‌توان به استفاده‌ای گسترده در فریم‌ورک‌هایی مثل سرور "Echo HTTP" و "Flask WSGI" اشاره داشت. برخی از کتابخانه‌ها نیز خوب هستند، مثل "Lodash" که برخی از قابلیت‌های مشترک و اضافی خاص را برای شما فراهم می‌کند.

این وابستگی‌های خارجی باید توسعه را برای شما آسان‌تر کند. این جزو مزیت‌های سیستم‌های پکیج است. در اینجا دم به تله دادن کار بسیار آسانی است. شاید تصور کنید که کتابخانه مورد نظر را پیدا کرده‌اید و قرار است تماماً از آن استفاده کنید. با ورود هر یک از این وابسته‌ها، شما خطر بی ثباتی، ناامنی و غیره را افزایش می‌دهید.

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

من در کنار وارد کردن کتابخانه‌ها از یک قانون ساده استفاده می‌کنم. زمانی آن کتابخانه را وارد خواهم کرد که بتوانم آن را در ۱۰ الی ۱۵ دقیقه بنویسم. در غیر اینصورت از یک کتابخانه خارجی استفاده خواهم کرد. عمل کردن به این ذهنیت سبب می‌شود تا موارد غیرضروری را وارد برنامه خود نکنید.

شما تا زمان مشخص، نیازی به انتزاعی کردن آن کد ندارید

یکی از تله‌هایی که می‌تواند به راحتی شما را درگیر خود کند، "انتزاعی کردن همه چیز" است. این تفکر که ممکن است بعدا از یک چیز دوباره استفاده کنم، می‌تواند به مسیرهای تاریک شی‌گرایی منتهی شود. اصل DRY می‌گوید که شما نباید خودتان را تکرار کنید. اما اینجا یک محدودیت وجود دارد که در آن یا شما زمان زیادی را صرف انتزاعی کردن می‌کنید یا زمان کافی برای منطقی نوشتن ندارید.

فقط کد خودتان را بنویسید! اگر متوجه شدید که باید یک تابع یا روشی مشابه به موارد قبلی را پیاده‌سازی کنید، به عقب برگردید و آن را با رعایت محدودیت‌های مناسب انتزاعی کنید. من از یک قاعده شخصی پیروی می‌کنم که در آن عقیده دارم اگر تابع قبل از انتزاعی شدن دارای ۳ خط ساده باشد، بیخیال آن شده و تنها آن را تکرار می‌کنم.

شما باید گاه به گاه پروژه خود را دوباره زنده کنید

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

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

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

شما گوگل نیستید

شاید شما گوگل باشید! اگر موضوع در مورد این است، پس چرا در حال مطالعه این مقاله هستید؟ نکته این است که شما گوگل، مایکروسافت، آمازون، توییتر و یا فیسبوک نیستید. شما به مدیریت کردن ۱۵۰۰۰۰ کانتینر در ۱۰۰۰۰ سرور و ۱۷ مرکز داده مختلف در سراسر دنیا نیازی ندارید. مشکلات شما معمولاً تاثیری در دنیا ندارند. چرا در این مورد صحبت می‌کنم؟ زیرا مقیاس شما باید پلتفرم عملیاتی شما را تعیین کند. آیا با مدیریت کردن صدها کانتینر، واقعا به Kubernetes احتیاج دارید؟ آیا واقعا باید آن را اجرا کنید؟ یا صرفاً می‌خواهید آن را به رزومه خود اضافه کنید؟

HashiCorp Nomad برای مشکلاتی در مقیاس کوچک تا متوسط مناسب است: تنظیم آن آسان است، نیاز کمی به تعمیر و نگهداری دارد، به خوبی مستند شده و امکان انتقال برنامه‌های شما به راحتی با آن امکان پذیر است زیرا مطابق با کانتینرها، فرایندهای سیستم و برنامه‌های JVM بومی کار می‌کند. اگر واقعا می‌خواهید از Kubernetes استفاده کنید، چرا این کار را تحت مدیریت Rancher انجام نمی‌دهید؟ این تمام موارد اشتباه و خراب را از بین می‌برد. اجرای سیستم‌های پیچیده‌ای مثل Kubernetes برای شرکت‌هایی مثل گوگل طراحی شده‌اند و مدیریت آن توسط یک تیم می‌تواند بسیار دشوار باشد. قصد دارم خیلی صریح به استارتاپ‌ها بگویم که به هر قیمتی شده باید از آن دوری کنند، مگر اینکه محصول آن‌ها به طور خاص Kubernetes را هدف قرار داده باشد.

فلسفه توسعه‌ی خود را براساس افراد موجود در اینترنت شکل ندهید

شما باید به قوانین شخصی و خاص خود برای برنامه‌ها و سبک توسعه فکر کنید. حتی ممکن است این ۱۰ مورد نیز از دید اشخاص دیگر اشتباه و نادرست باشند. به هر حال من فقط یک شخص اینترنتی هستم که شما مشغول خواندن مقاله‌اش هستید.

منبع

دیدگاه‌ها و پرسش‌ها

برای ارسال نظر لازم است ابتدا وارد سایت شوید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید