اکثر برنامه نویسها کلمات اختصاری رو دوست دارن و از اونها به مراتب در طول روز استفاده میکنن. کلماتی مثل MVP یا PoC خیلی رایج هستن. اما خب کلمات اختصاری هم وجود دارن که یکم چاشنی طنز و خلاقیت در اونها دیده میشه و خیلیامون دوس داریم ازشون استفاده کنیم؛ مثل SOLID، DRY یا KISS.
دونستن معنی و مفهوم هر کدوم از این کلمهها باعث میشه تا ما بهتر بتونیم با همکارامون ارتباط برقرار کنیم و به نوعی منظور هم دیگه رو بهتر بفهمیم.
DRY
این کلمه رو خیلیامون شنیدیم و معنیش رو هم اکثرمون میدونیم. این کلمه در واقع یک اصل در توسعهی نرم افزاره و مخفف Don’t Repeat Yourself هست. به این معنی که در هنگام کدنویسی، باید قطعه کدها و عملکردی در برنامتون رو که بیش از یکبار تکرار میکنید رو ماژولار کنید.
البته ماژولار کردن به این معنی نیست که یک تابعی که دوبار ازش استفاده کردید رو تبدیل به یک کتابخونه کنید یا ازش library بسازید! بلکه اگر منطق یکسانی در چندین قسمت از برنامتون وجود داره، اون رو درون یک تابع بنویسید. به این ترتیب از این به بعد فقط کافیه تابعی که یکبار نوشتید رو فراخونی کنید.
همچنین اگه به همون تابع در چندین پروژه نیاز دارید و اون رو بین پروژههای مختلف کپی میکنید، بهتره تا اون رو به یک کتابخونهی کوچیک تبدیل کنید و ازش استفاده کنید.
KISS
این کلمه در واقع مخفف عبارت Keep It Simple Stupid به مفهوم «ساده نگه داشتن» هست.
گاهی اوقات در هنگام حل مسائل مختلف ممکن هست در تلهای بیفتیم که اصولا با عنوان over-engineering شناخته میشه. به عبارت ساده تر، طبیعتا وقتی میخواید پَشه بکشید از بازوکا استفاده نمیکنید! پس سعی کنید از ابزاری ساده تر برای اینکار استفاده کنید.
طبیعتا گاهی اوقات در هر برنامهای یک سری منطق پیچیده نیاز هست. وقتی یک معماری ساده مناسب کار شما نیست، پس بهتره از یک معماری پیچیدهتر برای حل مشکلتون استفاده کنید. اما همیشه سعی کنید کدتون رو در ساده ترین حالت ممکن نگه دارید.
SOLID
این عبارت در واقع به عنوان یک اصل برنامه نویسی شناخته میشه:
- Single Responsibility Principle (اصل یگانگی مسئولیت)
- Open-Closed Principle (اصل باز – بسته)
- Liskov Substitution Principle (اصل جانشینی لیسکوف)
- Interface Segregation Principle (اصل تفکیک رابطها)
- Dependency Inversion Principle (اصل وارونگی وابستگی)
بهتره هرکدوم از این اصل ها رو با جزییات بیشتری بررسی کنیم تا بهتر و دقیق تر مفهوم SOLID رو درک کنیم.
- ما در اینجا قرار نیست که به طور کامل در مورد اصول SOLID صحبت کنیم؛ بلکه خیلی مختصر این اصول رو شرح میدیم.
Single Responsibility Principle
اصولا تابعها باید در برنامهی شما تنها یک کار را انجام دهند. هنگام برنامه نویسی تابعی شما باید از این اصل پیروی کنید. اگر تجربهی کار با خط فرمان لینوکس رو داشته باشید، با دستوراتی مثل ls یا cd آشنایی دارید. هرکدوم از این دستورات فقط و فقط یک وظیفه دارند و میتوانند کارهای مربوط به آن وظیفه را انجام دهند.
توابعی که مینویسید باید به قدری ساده باشن که فقط یک مسئولیت داشته باشن. برای رسیدن به رفتارهای پیچیده در برنامه، ورودی و خروجی این توابع ساده رو با هم ترکیب کنید تا به هدفتون برسید. برای مثال اگه داخل برنامتون تابعی با نام get_user_and_related_books دارید که منطق مرتبط برنامتون در اون پیاده سازی شده، بهتره تا منطق برنامتون رو در تابع get_user_books پیاده سازی کنید که یک user رو به عنوان ورودی دریافت میکند. user مربوط نیز از تابعی با نام get_user بدست میاد. به همین سادگی.
درسته که ما داریم اینجا در مورد توابع صحبت میکنیم. اما همین اصل رو میتونیم به معماری سرویسهامون هم تعمیم بدیم. به عنوان مثال برای پیاده سازی یک سرویس عظیم که تمام مسئولیتها و کارکردها رو مدیریت میکنه، میتونیم اون رو به میکروسرویسهای کوچکتری تقسیم کنیم که هرکدوم از اونها فقط یک مسئولیت دارن.
Open-Closed principle
این اصل به این اشاره داره که ماژولهای شما باید قابلیت گسترش و توسعهی بیشتر رو داشته باشن. اما نباید قابل تغییر باشن. اگه برنامه نویسی برای توسعهی رفتاری از برنامهی شما، مجبور باشه کد شما را به کلی تغییر بده، شما این اصل رو زیر پا گذاشتید.
کدهای شما باید به صورتی نوشته شده باشن که هر برنامه نویس دیگهای بتونه متدها و رفتارهایی به اون اضافه کنه، بدون اینکه نیاز باشه تا ماژولهای شما و یا رفتارهای فعلی برنامتون رو تغییر بده. به بیان کلی تر، قابلیت توسعهی کد فعلی شما برای سایرین، بدون نیاز به تغییر اساس کد شما.
Liskov Substitution Principle
به طور کلی این اصل بیانگر این است که: «اشیاءِ یک برنامه که از یک کلاس والد هستند، باید به راحتی و بدون نیاز به تغییر در برنامه، قابل جایگزینی با یکدیگر باشند.»
طبیعتا در اینجا ما با یک اصل از OOP روبرو هستیم. ما باید به صورت صحیح از ارث بری در قسمتهای مختلف برناممون استفاده کنیم.
برای درک بهتر این اصل، یه مثال رو با هم بررسی میکنیم. همونطور که میدونیم، در ریاضیات مربع نوع خاصی از مستطیل هست. این جمله به ما این حس رو میده که میتونیم این مفهوم رو با وراثت پیاده سازی کنیم. یعنی یک کلاس مربع بسازیم و کلاس مستطیل رو به عنوان کلاس پدر این کلاس تعریف کنیم. بنابراین طبق «اصل جانشینی لیسکوف» ما از این پس باید بتونیم هرجا که از مستطیل استفاده میکردیم، از مربع هم استفاده کنیم. فرض کنید متدهایی با نام setWidth و setHeight داخل کلاس مستطیل داریم. اما طبیعتا استفاده از این هر یک از این متدها در کلاس مربع بی فایده هست. چرا که برای مثال تغییر طول مربع باعث میشه تا عرض اون هم بطور خودکار تغییر کنه. بنابراین در اینجا ما اصل جانشینی لیسکوف رو زیر پا گذاشتیم و نمیتونیم از اشیا کلاس مربع در همون جاهایی که از کلاس مستطیل استفاده میکردیم استفاده کنیم.
به عبارت دیگر پیروی از این اصل باعث میشه تا ما به درستی از مفهوم وراثت موقع کد نویسی استفاده کنیم. پس بهتره همیشه موقع طراحی کلاسها در برناممون این اصل رو به یاد داشته باشیم.
Interface Segregation Principle
این اصل در واقع به این موضوع اشاره میکنه که شما نباید کلاسها و رابطهای برنامه رو طوری پیاده سازی کنید که سایر برنامه نویسهایی که قرار هست از کد شما استفاده کنن، نیاز باشه تا حتما تمام متدهای موجود در اونها رو پیاده سازی کنن. به بیان ساده تر، هیچ برنامه نویسی نباید مجبور به استفاده از متدهایی باشه که از اونها استفاده نمیکنه.
این اصل به طور کلی روی طراحی رابطها تمرکز داره. سعی کنید متدهای مختلف رو در رابطهای مختلف پیاده سازی کنید و به سایرین اجازه بدید تا بسته به نیازشون از هرکدوم از اونها استفاده کنن. به این ترتیب برنامه نویسی که از رابط شما استفاده میکنه، فقط از متدهایی اطلاع داره که به اونها نیاز داره. در واقع استفاده از ISP باعث سادگی در ایجاد تغییر و اصلاح کدها در طول زمان میشه.
البته توجه داشته باشید که در زبانی مثل پایتون، مفهوم رابط (interface) رو میتونید به نوعی دیگه با کمک abstract class ها پیاده سازی کنید.
Dependency Inversion Principle
اصل وارونگی وابستگی با نام دیگری یعنی تزریق وابستگی (dependency injection) هم شناخته میشه.
این اصل در واقع بیانگر این امر هست که ماژولهای سطح بالای برنامه نباید وابسته به ماژولهای سطح پایین باشن و باید به راحتی قابل استفادهی مجدد باشن. به بیان دیگه، هر نوع تغییر در ماژولهای سطح پایین نباید رفتار سایر ماژولهای سطح بالا رو تغییر بده. بدین منظور باید لایههایی پیاده سازی بشن تا این ماژولها از هم جدا شده و ارتباط بین اونها از طریق این لایهها برقرار بشه.
در واقع توضیح واضح این اصل کمی پیچیده هست. اما زمانی که شما دو اصل Open-Closed و Liskov Substitution رو در برنامتون پیاده سازی کنید، به طور خودکار اصل Dependency Inversion رعایت میشه.
- بسته به زبان برنامه نویسی مورد استفادتون میتونید با چند جستجوی ساده مثالهایی رو در مورد هرکدوم از اصول SOLID پیدا کنید تا بیشتر با اونها آشنا بشید.
YAGNI
این کلمه مخفف عبارت You ain’t gonna need it هست و به این موضوع اشاره داره که تا زمانی که به یک قابلیت در برنامتون نیازی ندارید، نباید اون رو پیاده سازی کنید.
به عبارت دیگه، در چارچوب توسعهی چابک (Agile) شما تنها باید روی تسکی که در حال حاضر دارید تمرکز کنید، نه به پیاده سازی قابلیتهایی که حس میکنید در آینده نیاز پیدا میکنین. در صورت انجام چنین کاری شما ماهیت گردش کار در چارچوب agile رو تغییر میدید. چراکه چارچوب agile روی بازخوردهای کوتاه مدت تمرکز داره و امکان داره تا آینده و مسیر پروژه دستخوش تغییرات اساسی بشه. بنابراین با اینکار شما در طولانی مدت یک ویژگی از سیستم رو ارائه میدید که هیچ نیازی بهش نبوده و کارایی اون در هیچ جای پروژه احساس نمیشه.
البته زمانی که در محیط waterfall در حال توسعه هستید، ممکن هست که پیروی از YAGNI مهم نباشد.
BDUF
این کلمه مخفف عبارت Big Design Up Front هست. این عبارت بیان کننده این هست که قبل از نوشتن اولین خط کد برای برنامتون، شما باید زمان بیشتری رو برای طراحی اون صرف کنید.
واضح است که این اصل در محیط waterfall میتونه کاملا رعایت بشه. محیطی که میتونید در اون به اندازه کافی زمان برای طراحی همه چیز صرف کنین؛ با این امید که وقتی شروع به توسعه میکنین، زمان زیادی را صرف پیدا کردن و رفع نقایص طراحی نکنید.
البته این روش مانند سایر روشهای دیگر دارای مخالفینی نیز هست. توسعه دهندگانی که در محیط چابک فعالیت میکنن، علاقهی زیادی به صرف بیش از حد زمان در این مرحله ندارن. چرا که گاهی اوقات ممکن هست برخی از اصول دستخوش تغییراتی بشه و دیگه از اهمیت سابق برخوردار نباشه.
SOC
یکی از اصولی که همیشه در هنگام طراحی معماری یک پروژه باید به اون توجه کنید چیزی نیست جز: Seperation of Concerns
این اصل به شما کمک میکنه تا توابع و ماژولها را در سرویسهای جداگانهای گروه بندی کنید. نکته مهم این هست که اگه شما در حال طراحی سیستمی هستید که با چندین مفهوم مختلف در بیزینس شما سر و کار داره (که معمولا اکثر سیستمها به این صورت هستن)، شما باید عملکرد هر بخش رو بسته به نوع کار اون در ماژولهای مختلفی دسته بندی کنید.
برای مثال فرض کنید شما بستری برای وبلاگ نویسی دارید که در اون کاربران شما میتونن نوشتههای خودشون رو منتشر کنن. شما میتونید یک سیستم واحد داشته باشید که همه چیز رو به تنهایی مدیریت کنه (مدیریت کاربران، پستها، تحلیل دادهها و …). اما اگه بخواهید از اصل SOC پیروی کنید، باید هرکدوم از این عملکردها رو در ماژولهایی مختلف مدیریت کنید و مسئولیتهای مختلف سیستم خودتون رو به واحدهایی مختلف تفکیک کنید. این امر دارای مزایایی نیز هست:
* مقیاس پذیری هر بخش در آینده راحت تر انجام میشه، بدون اینکه تداخلی در عملکرد سایر بخشها به وجود بیاد.
* زمانی که کدهای شما به هم پیوسته نیست، ایجاد تغییرات در یک بخش راحت تر انجام میشه.
* پلتفرم شما اکنون پایدارتر هست. اگه یکی از بخشهای سیستم شما دچار مشکل بشه، سیستم بطور بالقوه هنوز توانایی کارکرد داره (البته با امکانات کمتر)؛ اما به طور کامل از بین نمیره.
SOC میتونه برای طراحی API، معماری یک کتابخونه یا طراحی سایر موارد مورد استفاده قرار بگیره. به نوعی میشه گفت این اصل صرفاً در مورد کنترل روی مجموعهای از عملکرد سیستم هست که باهم ارتباط معنایی مشترکی دارن.
MVP
جدا از مسائل مربوط به برنامه نویسی، کلمات اختصاری دیگهای هم در دنیای نرم افزار وجود داره که ما معمولا از اونها استفاده میکنیم که دونستن اونها هم مهم هست.
MVP مخفف عبارت Minimum Viable Product هست و نشان دهندهی حداقل عملکردی هست که محصول شما باید داشته باشه تا بتونیم اون رو یک محصول واقعی و مناسب رشد و ترقی خطاب کنیم.
این یک روش عالی برای درک این نکته هست که آیا رسیدن به ۱۰۰٪ محصول مورد نظرتون باعث اتلاف وقت شما میشه؟ و اصلا محصول شما ارزش سرمایه گذاری داره یا نه. خروجی فاز MVP معمولا محصولی هست که اگرچه لزوماً آمادهی عرضه نیست، اما میتونه توسط یک عدهی محدودی از کابران مورد استفاده قرار بگیره که به نوبه خود بازخورد لازم رو برای درک دوام محصول در آینده ارائه میده.
POC
بر خلاف MVP که برای تهیه و برنامه ریزی به مقدار قابل توجهی تلاش نیاز داده، Proof of Concept در واقع یک نسخهی کوچکتر از اون هست. POC معمولا قبل از MVP قرار میگیره و تنها به عنوان بررسی و اثبات عملی بودن چیزی که قرار هست ساخته بشه منظور میشه.
همچنین POC ها معمولا به عنوان یک قطعه کدی هستند که دور ریخته میشن. شما اونها رو نمیسازین تا موندگار باشن؛ بلکه اونها ساخته میشن که تا نکتهای رو بیان کنن. به خاطر داشته باشین که ممکن است گاهی اوقات یک POC به تکامل برسد. اما این احتمال هم وجود داره که شاید نیاز باشه چندین POC برای بررسی یک موضوع بسازید. بنابراین نمیشه به نوعی برنامه ریزی کرد که حتما تمام اونها تبدیل به یک محصول واقعی بشن.
جمع بندی
تمام این کلمات اختصاری مهم هستن و برخی از این کلمات رو ممکن شما بارها و بارها در آموزشهای ویدیویی مختلف یا از همکارانتون شنیده باشید. حالا شما معنی و مفهوم هر کدوم از این کلمات رو میدونید.
آیا کلمات دیگهای هم هست که اینجا بهش اشاره نشده؟ خوشحال میشم اگه شما هم کلمهای اختصاری به دهنتون میرسه اون رو داخل بخش کامنتها بنویسید.