با سلام خدمت همه دوستان و همراهان همیشگی وب سایت فرازکُد:
کدنویسی با کیفیت بالا، همکاری بهتر در پروژههای توسعه نرمافزار را آسانتر میکند و همچنین در صرفهجویی زمان و انرژی برای بهبود، بهروزرسانی و نگهداری کد کمک میکند. در این مقاله، ابتدا با مفهوم “clean code” یا “کد تمیز” آشنا خواهیم شد و سپس به بررسی اصول و قواعدی که برای دستیابی به چنین کدی لازم است، خواهیم پرداخت. هر برنامهنویس میداند که بخش جذابترین این حرفه، آن لحظه است که کد بدون هیچ نقص و با خروجی مطابق انتظار اجرا میشود. بنابراین، تلاش اصلی برنامهنویسان بر روی نوشتن کدهایی است که در نهایت به درستی عمل کنند. اما این فرآیند میتواند منجر به تبدیل سورس کد از حالت تمیز به یک ساختار پیچیده و بیدرنگ شود.
- برنامه نویسی Front End چیست؟با سلام خدمت همه دوستان و همراهان همیشگی وب سایت فرازکد: برنامه نویسی فرانت اند (Front end) به بخش ظاهری توسعه وب اشاره دارد که به طور خلاصه شامل طراحی وب از ساختار سایت تا استایلهای مختلف مانند رنگها، پسزمینهها، اندازهها و انیمیشنها و … میشود.… خواندن بیشتر: برنامه نویسی Front End چیست؟
اگر از یک برنامهنویس درخواست کنید که یک قطعه کد طولانی برای بخش خاصی از یک پروژه بنویسد، احتمالاً با خوشحالی این پیشنهاد را پذیرفته خواهد کرد. اما اگر به او بگویید که کد آماده ای را تغییر دهد، احتمالاً تمایل کمتری به این کار نشان خواهد داد یا حتی با مقاومت آن را بپذیرد. علت این موضوع این است که بسیاری از ما به شیوهای که عادت داریم برنامهنویسی میکنیم، متمرکز هستیم که ممکن است برای دیگران دشوار باشد تا آن را درک کنند و تغییر دهند. در این نوشته، ما به بررسی مفهوم “کدنویسی تمیز” یا “clean code” خواهیم پرداخت و درباره اصول آن صحبت خواهیم کرد.
تعریف Clean Code (کد تمیز)
کدنویسی تمیز (Clean Code)، مجموعهای از اصول است که به شما این امکان را میدهد، کدی بنویسید که فهمیدن و تغییر دادن آن برای دیگران یا حتی برای خودتان در آینده آسان باشد. این اصول استانداردهایی را تعریف میکنند که رعایت آنها، شما را به عنوان یک برنامهنویس حرفهای شناخته میکند.
کدنویسی تمیز در محیطهای کاری گروهی دارای اهمیت بالایی است!
در متدولوژیهایی مانند Agile، کدنویسی تمیز به شدت توصیه میشود زیرا اعضای تیم اغلب ملزم به تکمیل و تغییر کدهای یکدیگر هستند. کد کثیف (Dirty Code) اصطلاحی است که مقابل کدنویسی تمیز قرار دارد.

عدم رعایت اصول کدنویسی تمیز، منجر به بینظمی و تکرار کدها میشود و کد شما را به Dirty Code تبدیل میکند. کدنویسی کیثف به معنای نوشتن کدهایی است که به صورت غیر بهینه و ناپایدار نوشته میشوند و معمولاً باعث ایجاد مشکلاتی در عملکرد، نگهداری و توسعه نرمافزار میگردند. این نوع کدنویسی میتواند به دلایل مختلفی از جمله کمبود تجربه، فشار زمانی، یا عدم توجه به بهترین شیوهها اتفاق بیفتد. در ادامه به برخی از ویژگیها و مشکلات کدنویسی کیثف اشاره میشود:
ویژگیهای کدنویسی کیثف
عدم خوانایی : کدهای کیثف معمولاً پیچیده و نامفهوم هستند و برای دیگر توسعهدهندگان سخت است که آنها را درک کنند.
عدم استفاده از استانداردها : در این نوع کدنویسی، معمولاً از استانداردهای برنامهنویسی پیروی نمیشود و این میتواند باعث بروز مشکلاتی در همکاری تیمی شود.
عدم بهینهسازی : کدهای کیثف معمولاً بهینه نیستند و ممکن است عملکرد نرمافزار را تحت تأثیر قرار دهند.
تکرار کد : در کدنویسی کیثف، ممکن است کدهای مشابه بارها و بارها تکرار شوند که این موضوع باعث افزایش حجم کد و کاهش کارایی میشود.
عدم تستپذیری : کدهای کیثف معمولاً به گونهای نوشته میشوند که تست کردن آنها دشوار است و این میتواند منجر به وجود باگهای غیرقابل شناسایی شود.
مشکلات ناشی از کدنویسی کیثف
مشکلات در نگهداری : نگهداری کد کیثف دشوار است و ممکن است نیاز به زمان و منابع بیشتری داشته باشد.
افزایش هزینهها : به دلیل مشکلات نگهداری و توسعه، هزینههای پروژه افزایش مییابد.
کاهش کیفیت نرمافزار : کدهای کیثف معمولاً باعث بروز باگها و مشکلات عملکردی میشوند که کیفیت نرمافزار را کاهش میدهد.
اصول کدنویسی تمیز چیست؟
اصول کدنویسی تمیز یا “کلین کد”، مجموعهای از روشها و تکنیکهایی است که به منظور افزایش کیفیت کد و بهبود فرآیند توسعه نرمافزار معرفی شدهاند. این اصول به برنامهنویسان کمک میکنند تا کد خود را به شکلی قابل فهم، قابل نگهداری و قابل توسعه بنویسند. در زیر به برخی از این اصول اشاره شده است:
- خواندن آسان
- تغییر پذیر
- قابل گسترش
- و قابل نگه داری
در توسعه ی نرم افزاری امروز غیر معمول نیست که کد نوشته شده Clean یا تمیز نباشد و این به سرعت منجر به خطا ها در طول توسعه یا مشکلات با برنامه های افزودنی می شود، به عنوان مثال زمانی که یک تغییر کوچک در کد ایجاد می شود باعث مجموعه ای از تغییرات در آینده می شود. نگهداری و توسعه نرم افزار به طور غیر ضروری پیچیده است که برای مقابله با این مشکل Clean Code Developer School منتشر شده است که این فرایند به سه بخش تقسیم میشود
- انجام تجزیه و تحلیل اولیه با پیروی از طرح کد، معروف به تجزیه کد و طراحی کد که این نوع از پروژه ی اصلی مجزاست (زمین سبز یا زمین قهوه ای)
- توسعه تدریجی کد به صورت همکاری نزدیک با مشتریان همراه یادگیری و واکنش پذیری ( روش چابک Agile)
- تفاهیم روش های راهنما و ارزش گذاری به همراه تمرینات و شیوه های اساسی Clean Code
این رویکرد ها از مشکلات فنی کد نویسی جلوگیری می کنند یا حداقل آن ها را تا حد پایین نگه می دارند. اگر چه تلاش زیادی برای پیاده سازی Clean Code در ابتدا زیاد است،ولی خیلی سریع تاثیر مثبتش را در چرخه تولید نرم افزار نشان میدهد، Clean Code نه تنها از لحاظ تکنولوژی پایدار است بلکه صرفه ی اقتصادی نیز دارد.
توسعه Clean Code
در زمانی که آثار اولیه Robert C. Martin به بنام ” Clean Code: A Handbook of Agile Software Craftsmanship” و Dustin Boswell با عنوان “The Art of Readable Code” به صورت ویژه بر روی سادگی و متمرکز بودن کد اشاره می کنند و همچنین به فرایند توسعه نرم افزار می نگرند که تعریفی از ارزش ها و اصول و شیوه های متعدد است علاوه بر این ساختار یک نرم افزار مبنایی برای تکامل بر اساس نیاز های جدید فراهم میکند و بدون ساختار هزینه ویژگی های جدید به طور تصاعدی افزایش می یابد به صورتی که اضافه کردن ساختار مورد نظر در مراحل میانی توسعه نرم افزار دشوار است. به همین خاطر در توسعه Clean Code این ضرب المثل صدق می کند : ابتدا تحلیل و سپس پیاده سازی یا به بیان دیگر ابتدا تمیز فکر کنید و سپس تمیز اجرا کنید.
ارزش ها در Clean Code
رویکرد پیاده سازی در Clean Code بر چهار پایه استوار است
- تغییر پذیری
- صحت
- بهره وری تولید
- پیشرفت مداوم
تغییر پذیری : نرم افزار مانند موجودی جان دار است، بسیار بیشتر از چیزی که در ابتدا مجسم می شد بهبود پیدا می کند خودش را وفق و ارتقا می دهد، هر چقدر که نرم افزار به آسانی بتواند خودش را با تغییرات وفق دهد تغییر پذیر تر است.
صحت : صحت به عنوان یک ارزش شاید کمی پیش و پا افتاده به نظر برسد ولی بیشتر از این چیز هاست به طور مثال اجرای توابع، استفاده صحیح از کلاس ها متد ها در توسعه نرم افزار، معنای صحت کد نویسی را تعریف می کنند.
بهره وری تولید : به دو دیدگاه مجزا در توسعه نرم افزار گفته می شود که شامل :
- توسعه نرم افزار باعث تلاش و صرف وقت می شود، کد نویسی که اصلاح و گسترش آن دشوار است که هر چه نرم افزار گسترده تر و طولانی تر توسعه پیدا کند، این مشکلات نیز بیشتر میشوند. بهره وری تولید به این معنی است که یک نرم افزار را سال ها توسعه داد زیرا که در این روش بر Clean Code تاکید می شود.
- راندمان تولید معیاری برای سایر ارزش ها است، از یک سو برای جلوگیری از افزایش تلاش بی پایان برای اطمینان از صحت نرم افزار و از سویی دیگر به مانند آبکاری طلا که در آن بیشتر از چیزی که با مشتری توافق شده پروژه توسعه داده می شود و یا با توسعه بیش از حد که در آن نرم افزار کیفیتی بالاتر از درخواست مشتری خواهد داشت
پیشرفت مداوم :به بهبود مستمر در پیاده سازی نرم افزار اشاره دارد به تکامل توسعه دهندگان که با روش های خود مقابله کنند به این صورت که سوالات زیر میتواند مورد توجه قرار گیرند
- چه تجربیاتی از برنامه نویسی به صورت جفتی Pair یا Mob به وجود آمد؟
- چه چیزی باعث Code smells شد؟
- چگونه می توان همکاری با تیم و مشتریان را بهبود داد؟
- چرا ما در حال یاد گیری نظرات بر روی کد ها هستیم؟
پیشرفت مداوم ارزش ها را به صورت مداوم بهبود می دهد و محوریت آن کار تیمی است.
در کدنویسی تمیز (Clean Code)، استفاده از نامهای واضح و توصیفی برای متغیرها، توابع و کلاسها از اهمیت بالایی برخوردار است. این ویژگی به دیگر توسعهدهندگان کمک میکند تا به راحتی کد را درک کنند و از آن استفاده کنند. در اینجا به بررسی ویژگیهای اسامی تمیز و ارائه یک مثال کد جاوا میپردازیم.
public class C {
private int a;
public void b(int x) {
a += x;
}
public int c() {
return a;
}
}
در این کد، نامهای C
, a
, b
, x
, و c
به هیچ وجه توصیفی نیستند و فهمیدن عملکرد این کلاس دشوار است.
ویژگیهای اسامی تمیز
توصیفی بودن : نامها باید به وضوح بیان کنند که متغیر، تابع یا کلاس چه کاری انجام میدهد یا چه چیزی را نمایندگی میکند.
مثال: به جای temp
از temperature
استفاده کنید.
بد:
int d; // d چیست؟
خوب:
int distance; // فاصله را نشان میدهد.
کوتاه و مختصر : نامها باید تا حد ممکن کوتاه باشند، اما در عین حال معنیدار و توصیفی باشند.
مثال: به جای getUserDataFromDatabase از fetchUserData استفاده کنید.
بد:
int numberOfUsersInTheSystem; // خیلی طولانی است.
خوب:
int userCount; // مختصر و واضح است.
استفاده از کنوانسیونها : پیروی از کنوانسیونهای نامگذاری (مانند camelCase برای متغیرها و PascalCase برای کلاسها) به خوانایی کد کمک میکند.
مثال: userName برای متغیرها و UserAccount برای کلاسها.
بد:
public class useraccount { // نام کلاس باید PascalCase باشد.
خوب:
public class UserAccount { // نام کلاس به درستی نوشته شده است.
اجتناب از اختصارات غیرمعمول : استفاده از اختصارات میتواند منجر به سوءتفاهم شود. بهتر است از نامهای کامل و واضح استفاده شود.
مثال: به جای num از numberOfItems استفاده کنید.
بد:
int qty; // qty ممکن است مشخص نباشد.
خوب:
int quantity; // واضح و قابل فهم است.
استفاده از نامهای افعالی برای توابع :
بد:
public void dataProcess() { // نام تابع به وضوح کار را نشان نمیدهد.
خوب:
public void processData() { // نام تابع واضحتر و توصیفیتر است.
استفاده از نامهای اسمی برای کلاسها :
بد:
public class ManageOrders { // نام کلاس باید نمایانگر موجودیت باشد.
خوب:
public class Order { // نام کلاس به وضوح نمایانگر یک موجودیت است.
قابل فهم برای دیگران :
بد:
boolean flag; // flag چه چیزی را نشان میدهد؟
خوب:
boolean isUserActive; // واضح و قابل فهم است.
اجتناب از نامهای مشابه :
بد:
public void calculateArea() { }
public void areaCalculation() { } // نامها مشابه هستند و ممکن است گیجکننده باشند.
خوب:
public void calculateCircleArea() { }
public void calculateRectangleArea() { } // نامها مشخص و متمایز هستند.
مناسب با دامنه کاربرد :
بد:
double a; // a چه چیزی را نشان میدهد؟
خوب:
double accountBalance; // نام مشخص و مرتبط با دامنه است.
استفاده از نامهای خاص به جای عمومی :
بد:
List<String> data; // data خیلی عمومی است.
خوب:
List<String> userNames; // نام خاصتر و توصیفیتر است.
public class BankAccount {
private int balance;
public void deposit(int amount) {
balance += amount;
}
public int getBalance() {
return balance;
}
}
در این نسخه، نامگذاری به وضوح بیانگر عملکرد کلاس و متدها است:
BankAccount : نام کلاس به وضوح نشاندهنده این است که این کلاس مربوط به یک حساب بانکی است.
balance : متغیر نشاندهنده موجودی حساب است.
deposit : نام متد به وضوح بیان میکند که این متد برای واریز پول به حساب است.
getBalance : نام متد به وضوح نشاندهنده این است که این متد موجودی حساب را برمیگرداند.
استفاده از نامهای تمیز و توصیفی در کدنویسی نه تنها به خوانایی و فهم بهتر کد کمک میکند، بلکه باعث میشود که نگهداری و توسعه نرمافزار آسانتر شود. این اصول از جمله اصول کلیدی کدنویسی تمیز هستند که باید در هر پروژهای رعایت شوند.
قانون 30/30/30
قانون 30/30/30 در کدنویسی تمیز (Clean Code) به یک اصل راهنما در طراحی و نوشتن کد اشاره دارد که به منظور افزایش خوانایی و نگهداری کد به کار میرود. این قانون به طور خاص به طول و ساختار کد مربوط میشود و به توسعهدهندگان توصیه میکند که کد خود را به گونهای بنویسند که در طول زمان قابل فهم و قابل نگهداری باشد. در زیر به توضیح این قانون میپردازیم:
هر توسعهدهنده باید بتواند کدی را که نوشته شده است، در عرض 30 ثانیه درک کند. این به این معنی است که نامگذاریها، ساختار و منطق کد باید به گونهای باشد که فهم آن آسان باشد و نیاز به توضیحات طولانی نداشته باشد.
مثال: به جای استفاده از نامهای مبهم مانند x یا `temp
به طور میانگی کمتر از 30خط کد در متد باشد
بهطور میانگین کمتر از 30 متد درون هر کلاس (حدود 900 خط کد)
به طور میانگین کمتر از 30 کلاس درون یک پکیچ (حدود 27000 خط کد)
فاصله های خطوط کد
فاصلههای خطوط کد در کدنویسی تمیز (Clean Code) به عنوان ابزاری برای افزایش خوانایی و سازماندهی کد به کار میروند. استفاده مناسب از فاصلهها میتواند به توسعهدهندگان کمک کند تا ساختار کد را بهتر درک کنند و به راحتی بخشهای مختلف آن را شناسایی کنند. در ادامه به بررسی این موضوع و ارائه مثالهایی میپردازیم.
اهمیت فاصلههای خطوط کد
افزایش خوانایی : فاصلههای مناسب باعث میشوند که کد به راحتی قابل خواندن و درک باشد.
تفکیک منطقی بخشها : با استفاده از فاصلهها میتوان بخشهای مختلف کد مانند متدها، کلاسها و بلوکهای کد را از هم تفکیک کرد.
کاهش سردرگمی : فاصلههای مناسب میتوانند از ایجاد سردرگمی در کد جلوگیری کنند و به توسعهدهندگان کمک کنند تا به راحتی به نقاط مختلف کد دسترسی پیدا کنند.
مثالی از فاصلههای خطوط کد
استفاده از فاصله بین متدها میتواند به تفکیک آنها کمک کند و خوانایی کد را افزایش دهد.
بد:
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
}
خوب:
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
}
کامنت گذاری در clean code
کامنتگذاری در کدنویسی تمیز (Clean Code) یکی از اصول مهم است که به بهبود خوانایی و درک کد کمک میکند. با این حال، کامنتگذاری باید بهگونهای انجام شود که مؤثر و مفید باشد. در ادامه به اهمیت کامنتگذاری، بهترین شیوهها و مثالهایی از آن میپردازیم.
اهمیت کامنتگذاری
افزایش خوانایی : کامنتها میتوانند به توضیح بخشهای پیچیده کد کمک کنند و فهم آنها را آسانتر کنند.
مستندسازی : کامنتها میتوانند به عنوان مستندات داخلی کد عمل کنند و توضیحات لازم را برای توسعهدهندگان دیگر فراهم کنند.
تسهیل نگهداری : با وجود کامنتهای مناسب، توسعهدهندگان میتوانند تغییرات و بهروزرسانیها را راحتتر انجام دهند.
بهترین شیوههای کامنتگذاری
توضیح دادن “چرا” نه “چی”: کامنتها باید به توضیح چرایی یک تصمیم یا روش خاص بپردازند، نه اینکه فقط بگویند کد چه کاری انجام میدهد.
بد:
// این تابع برای جمع دو عدد است
public int add(int a, int b) {
return a + b;
}
خوب:
// این تابع برای محاسبه مجموع دو عدد ورودی استفاده میشود
// از آن در محاسبات مالی استفاده میشود
public int add(int a, int b) {
return a + b;
}
کوتاه و مختصر بودن:
کامنتها باید به اندازه کافی کوتاه و مختصر باشند تا پیام خود را به وضوح منتقل کنند.
بد:
// این تابع یک عدد را از ورودی میگیرد و آن را به عددی بزرگتر تبدیل میکند
public int convertToLargerNumber(int number) {
return number + 1;
}
خوب:
// افزایش عدد ورودی به ۱
public int convertToLargerNumber(int number) {
return number + 1;
}
استفاده از کامنتهای TODO:
از کامنتهای TODO برای اشاره به کارهایی که باید در آینده انجام شود، استفاده کنید.
مثال:
// TODO: بهینهسازی این تابع
public void processData() {
// کد فعلی
}
اجتناب از کامنتهای غیرضروری:
از کامنتهایی که اطلاعات اضافی یا تکراری ارائه میدهند، پرهیز کنید. کد باید به اندازه کافی گویا باشد.
بد:
// متغیر x برای ذخیره عدد ۱۰
int x = 10;
خوب:
int ten = 10; // نام متغیر به وضوح نشاندهنده مقدار است
استفاده از کامنتهای مستنداتی:
از کامنتهای مستنداتی (Javadoc در جاوا) برای توصیف کلاسها و متدها استفاده کنید.
مثال:
/**
* محاسبه مجموع دو عدد.
*
* @param a عدد اول
* @param b عدد دوم
* @return مجموع دو عدد
*/
public int add(int a, int b) {
return a + b;
}
کامنتگذاری صحیح و مؤثر در کدنویسی تمیز به فهم بهتر کد و تسهیل نگهداری آن کمک میکند. با رعایت بهترین شیوههای کامنتگذاری، توسعهدهندگان میتوانند کدهایی بنویسند که نه تنها برای خودشان بلکه برای دیگران نیز قابل فهم و نگهداری باشد.
قانون KISS (Keep It Simple, Stupid)
قوانین KISS (Keep It Simple, Stupid) یکی از اصول مهم در برنامهنویسی و توسعه نرمافزار است که به سادگی و وضوح کد تأکید میکند. در زمینه Clean Code (کد تمیز)، این اصل به این معناست که کد باید به گونهای نوشته شود که ساده، قابل فهم و نگهداری باشد. در ادامه، به توضیح این اصل و نحوهی پیادهسازی آن در Clean Code میپردازیم:
- سادگی در طراحی کد را ساده نگهدارید : از پیچیدگیهای غیرضروری پرهیز کنید. طراحی سیستم باید به گونهای باشد که فهم آن آسان باشد.
- وضوح کد استفاده از نامهای معنادار : نامگذاری متغیرها، توابع و کلاسها باید واضح و گویا باشد تا دیگران به راحتی متوجه شوند که هر بخش از کد چه کاری انجام میدهد.
- مستندسازی مستندات مناسب : اگر بخشی از کد پیچیده است و نیاز به توضیحات بیشتری دارد، حتماً مستندات لازم را ارائه دهید. اما سعی کنید کد خود را به گونهای بنویسید که نیازی به توضیحات زیاد نداشته باشد.
- تستپذیری کد تستپذیر : کدی که ساده و قابل فهم باشد، معمولاً تستپذیری بهتری دارد. این امر به شما کمک میکند تا با اطمینان بیشتری تغییرات را اعمال کنید.
- بازخورد و اصلاح بازخورد از دیگران : کد خود را با دیگران به اشتراک بگذارید و از بازخورد آنها استفاده کنید. این کار میتواند به شفافتر شدن کد و سادهتر شدن آن کمک کند.
- اجتناب از راهحلهای پیچیده : اگر میتوانید با یک روش سادهتر به نتیجه برسید، از راهحلهای پیچیده و غیرضروری خودداری کنید.
- تقسیم کد به توابع و ماژولهای کوچکتر : هر تابع یا ماژول باید یک مسئولیت مشخص داشته باشد. این کار باعث میشود کد قابل فهمتر و نگهداری آن آسانتر شود.
- اصلاح مداوم : به طور مرتب کد خود را مرور کرده و به دنبال فرصتهایی برای سادهسازی آن باشید.
اصل KISS در Clean Code به شما کمک میکند تا کدی بنویسید که نه تنها کار میکند، بلکه دیگران نیز به راحتی میتوانند آن را بخوانند و درک کنند. با رعایت این اصل، میتوانید کدی تولید کنید که از نظر کیفیت و نگهداری در سطح بالایی قرار داشته باشد. برای درک بهتر اصل KISS (Keep It Simple, Stupid) در Clean Code، بیایید یک مثال ساده از کد را بررسی کنیم. این مثال شامل دو نسخه از یک تابع است که یک عدد را بررسی میکند تا ببیند آیا آن عدد فرد است یا زوج. ما دو نسخه از این تابع را بررسی میکنیم: یکی پیچیده و دیگری ساده.
نسخه پیچیده (غیر KISS)
public class NumberChecker {
public static String checkNumber(int num) {
String result;
if (num % 2 == 0) {
result = "Even";
} else {
result = "Odd";
}
if (num < 0) {
result += " (Negative)";
} else if (num > 0) {
result += " (Positive)";
} else {
result += " (Zero)";
}
return result;
}
public static void main(String[] args) {
System.out.println(checkNumber(-4)); // Output: Even (Negative)
System.out.println(checkNumber(3)); // Output: Odd (Positive)
}
}
تجزیه و تحلیل نسخه پیچیده
- پیچیدگی: این تابع چندین مسئولیت دارد: بررسی زوج یا فرد بودن عدد و همچنین تعیین مثبت، منفی یا صفر بودن آن.
- عدم وضوح: با افزایش تعداد شرایط، خواندن و درک کد دشوارتر میشود.
- تستپذیری پایین: این کد به دلیل پیچیدگیاش، تست کردن آن دشوارتر است.
نسخه ساده (KISS)
حالا بیایید این تابع را به گونهای سادهتر و با رعایت اصل KISS بازنویسی کنیم:
public class NumberChecker {
public static boolean isEven(int num) {
return num % 2 == 0;
}
public static String classifyNumber(int num) {
String result = isEven(num) ? "Even" : "Odd";
if (num < 0) {
result += " (Negative)";
} else if (num > 0) {
result += " (Positive)";
} else {
result += " (Zero)";
}
return result;
}
public static void main(String[] args) {
System.out.println(classifyNumber(-4)); // Output: Even (Negative)
System.out.println(classifyNumber(3)); // Output: Odd (Positive)
}
}
تجزیه و تحلیل نسخه ساده
- ساده بودن : تابع
isEven
تنها مسئولیت بررسی زوج بودن عدد را دارد و تابعclassifyNumber
فقط نوع عدد را مشخص میکند. - وضوح : نام توابع واضح و معنادار هستند و به راحتی میتوان فهمید که هر تابع چه کاری انجام میدهد.
- تستپذیری : هر تابع به راحتی قابل تست است و میتوان به سادگی
isEven
را برای آزمایش زوج بودن عدد وclassifyNumber
را برای بررسی نوع عدد تست کرد.
با پیروی از اصل KISS، ما کدی سادهتر، قابل فهمتر و قابل نگهداریتر ایجاد کردیم. این کار به توسعهدهندگان دیگر کمک میکند تا به راحتی کد را بخوانند و درک کنند، و همچنین به تست و اصلاح آن کمک میکند.
قانون DRY (Don’t Repeat Yourself)
اصل DRY (Don’t Repeat Yourself) یکی از اصول کلیدی در برنامهنویسی و توسعه نرمافزار است که به جلوگیری از تکرار کد و اطلاعات مشابه تأکید میکند. این اصل به این معناست که هر قطعه اطلاعات یا منطق باید تنها در یک مکان در برنامه وجود داشته باشد. در ادامه، به توضیح جزئیات این اصل و نحوهی پیادهسازی آن در Clean Code میپردازیم.
مفهوم اصل DRY
- اجتناب از تکرار : هدف اصلی DRY این است که کد تکراری را کاهش دهد. اگر یک منطق یا داده در چندین مکان از کد تکرار شود، در صورت نیاز به تغییر، باید در همهجا تغییر کند که این کار میتواند منجر به بروز خطاهای ناخواسته شود.
- افزایش نگهداریپذیری : با کاهش تکرار، نگهداری و بهروزرسانی کد آسانتر میشود. تغییرات تنها در یک مکان اعمال میشوند و این به کاهش احتمال بروز خطا کمک میکند.
مزایای پیادهسازی اصل DRY
- کاهش خطا : با کاهش تکرار، احتمال بروز خطا در هنگام بهروزرسانی کد کاهش مییابد.
- سازگاری : کد DRY باعث میشود که تغییرات در منطق یا دادهها به صورت متمرکز انجام شود و این به سازگاری کد کمک میکند.
- افزایش خوانایی : کد DRY معمولاً خواناتر است، زیرا منطق مشابه در یک مکان متمرکز شده است.
پیادهسازی اصل DRY
برای پیادهسازی اصل DRY، میتوان از روشها و تکنیکهای مختلفی استفاده کرد:
- ایجاد توابع و متدها: به جای تکرار کد، میتوان منطق مشترک را در یک تابع یا متد قرار داد و در جاهای مختلف فراخوانی کرد.
- استفاده از کلاسها و شیگرایی: در برنامهنویسی شیگرا، میتوان از کلاسها و وراثت برای کاهش تکرار استفاده کرد.
- استفاده از الگوهای طراحی: الگوهای طراحی میتوانند به کاهش تکرار و بهبود ساختار کد کمک کنند.
برای درک بهتر اصل DRY، بیایید یک مثال ساده از کد جاوا را بررسی کنیم.
نسخه بدون رعایت اصل DRY
public class Invoice {
public double calculateTotal(double price, int quantity) {
double tax = price * quantity * 0.1; // 10% tax
double total = (price * quantity) + tax;
return total;
}
public double calculateDiscountedTotal(double price, int quantity, double discount) {
double tax = price * quantity * 0.1; // 10% tax
double total = (price * quantity) + tax;
total -= discount;
return total;
}
}
تجزیه و تحلیل کد :
- در اینجا، محاسبه مالیات در دو مکان تکرار شده است. این میتواند منجر به بروز خطا در صورت تغییر نرخ مالیات شود.
public class Invoice {
private double calculateTax(double price, int quantity) {
return price * quantity * 0.1; // 10% tax
}
public double calculateTotal(double price, int quantity) {
double tax = calculateTax(price, quantity);
return (price * quantity) + tax;
}
public double calculateDiscountedTotal(double price, int quantity, double discount) {
double tax = calculateTax(price, quantity);
double total = (price * quantity) + tax;
total -= discount;
return total;
}
}
تجزیه و تحلیل نسخه DRY
- در این نسخه، محاسبه مالیات به یک تابع جداگانه منتقل شده است. این کار باعث کاهش تکرار و افزایش نگهداریپذیری کد میشود. اگر نرخ مالیات تغییر کند، فقط کافی است که آن را در یک مکان تغییر دهید.
اصل DRY در Clean Code به شما کمک میکند تا کدی تمیزتر، قابل نگهداریتر و با احتمال بروز خطای کمتر ایجاد کنید. با رعایت این اصل، میتوانید از تکرار غیرضروری جلوگیری کرده و کیفیت کد خود را بهبود بخشید.
قوانین SOLID
قوانین SOLID مجموعهای از اصول طراحی شیگرا هستند که به توسعهدهندگان کمک میکنند تا کدهای تمیز، قابل نگهداری و مقیاسپذیر بنویسند. این اصول به بهبود طراحی نرمافزار و کاهش پیچیدگی کمک میکنند. در ادامه، به توضیح هر یک از این اصول و نحوهی پیادهسازی آنها در Clean Code میپردازیم.
S – Single Responsibility Principle (اصل مسئولیت واحد)
هر کلاس باید تنها یک مسئولیت داشته باشد و بهتنهایی آن مسئولیت را انجام دهد. این اصل به کد کمک میکند تا قابل فهمتر و نگهداریتر باشد.
مثال:
// نقض اصل مسئولیت واحد
public class User {
private String name;
private String email;
public void save() {
// کد برای ذخیره کاربر در دیتابیس
}
public void sendEmail() {
// کد برای ارسال ایمیل
}
}
// رعایت اصل مسئولیت واحد
public class User {
private String name;
private String email;
}
public class UserRepository {
public void save(User user) {
// کد برای ذخیره کاربر در دیتابیس
}
}
public class EmailService {
public void sendEmail(User user) {
// کد برای ارسال ایمیل
}
}
O – Open/Closed Principle (اصل باز/بسته)
کلاسها باید برای گسترش باز و برای تغییر بسته باشند. این به این معناست که میتوانید رفتار کلاسها را بدون تغییر کد موجود گسترش دهید.
مثال:
// نقض اصل باز/بسته
public class Rectangle {
public double width;
public double height;
}
public class AreaCalculator {
public double calculateArea(Rectangle rectangle) {
return rectangle.width * rectangle.height;
}
}
// رعایت اصل باز/بسته
public interface Shape {
double area();
}
public class Rectangle implements Shape {
public double width;
public double height;
public double area() {
return width * height;
}
}
public class Circle implements Shape {
public double radius;
public double area() {
return Math.PI * radius * radius;
}
}
public class AreaCalculator {
public double calculateArea(Shape shape) {
return shape.area();
}
}
L – Liskov Substitution Principle (اصل جانشینی لیسکوف)
کلاسهای فرعی باید بتوانند بهجای کلاسهای پایه خود استفاده شوند بدون اینکه رفتار برنامه تغییر کند. این اصل به تضمین سازگاری بین کلاسهای پایه و فرزندان کمک میکند.
مثال:
// نقض اصل جانشینی لیسکوف
public class Bird {
public void fly() {
// پرواز کردن
}
}
public class Ostrich extends Bird {
@Override
public void fly() {
throw new UnsupportedOperationException("Ostriches can't fly");
}
}
// رعایت اصل جانشینی لیسکوف
public interface Bird {
void makeSound();
}
public class Sparrow implements Bird {
public void makeSound() {
// صدا زدن
}
public void fly() {
// پرواز کردن
}
}
public class Ostrich implements Bird {
public void makeSound() {
// صدا زدن
}
}
I – Interface Segregation Principle (اصل تفکیک رابط)
یک رابط نباید مجبور به پیادهسازی متدهایی باشد که مورد نیازش نیست. به عبارت دیگر، رابطها باید کوچک و خاص باشند.
مثال:
// نقض اصل تفکیک رابط
public interface Animal {
void fly();
void swim();
}
// رعایت اصل تفکیک رابط
public interface Flyable {
void fly();
}
public interface Swimmable {
void swim();
}
public class Duck implements Flyable, Swimmable {
public void fly() {
// پرواز کردن
}
public void swim() {
// شنا کردن
}
}
public class Fish implements Swimmable {
public void swim() {
// شنا کردن
}
}
D – Dependency Inversion Principle (اصل وارونگی وابستگی)
ماژولهای سطح بالا نباید به ماژولهای سطح پایین وابسته باشند. هر دو باید به رابطها وابسته باشند. همچنین، رابطها نباید به جزئیات وابسته باشند، بلکه جزئیات باید به رابطها وابسته باشند.
مثال:
// نقض اصل وارونگی وابستگی
public class UserService {
private UserRepository userRepository = new UserRepository();
public void saveUser(User user) {
userRepository.save(user);
}
}
// رعایت اصل وارونگی وابستگی
public interface UserRepository {
void save(User user);
}
public class UserService {
private UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void saveUser(User user) {
userRepository.save(user);
}
}
قوانین SOLID به توسعهدهندگان کمک میکنند تا کدهایی تمیز، قابل نگهداری و مقیاسپذیر بنویسند. با رعایت این اصول، میتوانید از بروز مشکلاتی مانند پیچیدگی بیش از حد، تکرار کد و نگهداری دشوار جلوگیری کنید و در نتیجه نرمافزار بهتری تولید کنید.
قانون YAGNI
اصل YAGNI (You Aren’t Gonna Need It) یکی از اصول کلیدی در توسعه نرمافزار و برنامهنویسی تمیز (Clean Code) است که به توسعهدهندگان توصیه میکند از پیادهسازی ویژگیها و قابلیتهایی که در حال حاضر به آنها نیاز ندارند، خودداری کنند. این اصل به جلوگیری از پیچیدگی و افزایش نگهداریپذیری کد کمک میکند.
مفهوم YAGNI
- اجتناب از اضافهکاری : YAGNI تأکید دارد که شما باید فقط آنچه را که در حال حاضر نیاز دارید پیادهسازی کنید و از پیشبینی نیازهای آینده خودداری کنید. این کار به کاهش حجم کد و جلوگیری از اضافهکاری کمک میکند.
- تمرکز بر نیازهای فعلی : با پیادهسازی تنها آنچه که در حال حاضر مورد نیاز است، میتوانید بر روی کیفیت کد و عملکرد آن تمرکز کنید.
مزایای YAGNI
- کاهش پیچیدگی : با جلوگیری از اضافهکاری، کد سادهتر و قابل فهمتر میشود.
- کاهش هزینههای نگهداری : کدهای اضافی که در حال حاضر مورد نیاز نیستند، میتوانند به مشکلات نگهداری و بهروزرسانی منجر شوند.
- افزایش سرعت توسعه : با تمرکز بر نیازهای فعلی، میتوانید سریعتر توسعه دهید و زمان کمتری را صرف ویژگیهای غیرضروری کنید.
برای درک بهتر اصل YAGNI، بیایید یک مثال ساده در جاوا بررسی کنیم.
نسخه بدون رعایت YAGNI
در این مثال، فرض کنید که ما یک کلاس برای مدیریت حسابهای بانکی داریم و توسعهدهنده تصمیم میگیرد که قابلیتهای اضافی را پیادهسازی کند که در حال حاضر مورد نیاز نیستند.
public class BankAccount {
private double balance;
private String accountNumber;
private String accountHolderName;
public BankAccount(String accountNumber, String accountHolderName) {
this.accountNumber = accountNumber;
this.accountHolderName = accountHolderName;
this.balance = 0.0;
}
// متد برای واریز وجه
public void deposit(double amount) {
balance += amount;
}
// متد برای برداشت وجه
public void withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
}
}
// متد اضافی برای محاسبه بهره
public double calculateInterest() {
// فرض کنید که نرخ بهره 5% است
return balance * 0.05;
}
// متد اضافی برای چاپ تاریخچه تراکنشها
public void printTransactionHistory() {
// این متد هنوز پیادهسازی نشده است
}
}
در این مثال، متد calculateInterest
و printTransactionHistory
به کد اضافه شدهاند، در حالی که در حال حاضر هیچ نیازی به آنها وجود ندارد. این کار باعث افزایش پیچیدگی کد میشود و نگهداری آن را دشوارتر میکند.
نسخه با رعایت YAGNI
حالا بیایید کد را به گونهای سادهتر و با رعایت اصل YAGNI بازنویسی کنیم:
public class BankAccount {
private double balance;
private String accountNumber;
private String accountHolderName;
public BankAccount(String accountNumber, String accountHolderName) {
this.accountNumber = accountNumber;
this.accountHolderName = accountHolderName;
this.balance = 0.0;
}
// متد برای واریز وجه
public void deposit(double amount) {
balance += amount;
}
// متد برای برداشت وجه
public void withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
}
}
// متد برای دریافت موجودی
public double getBalance() {
return balance;
}
}
در این نسخه، متدهای اضافی حذف شدهاند و ما تنها بر روی نیازهای فعلی تمرکز کردهایم. این کار باعث میشود کد سادهتر، قابل فهمتر و نگهداریپذیرتر باشد.
اصل YAGNI به توسعهدهندگان کمک میکند تا از پیادهسازی ویژگیها و قابلیتهای غیرضروری خودداری کنند و بر روی نیازهای فعلی تمرکز کنند. با رعایت این اصل، میتوانید کدی تمیزتر و با کیفیتتر تولید کنید که نگهداری و بهروزرسانی آن آسانتر باشد
6 پاسخ
بسیار مفید بود، ممنونم از سایت خوبتون
باتشکر از شما
مطالب مفیدی بود
تشکر ازشما
محتوای مفیدی بود .
لطفا مطالبی مربوط به آموزش جاوا هم قرار دهید .
باسلام وقت بخیر
خواهش میکنم