یکی از مهمترین ویژگیهای سیستمهایی که طراحی خوبی دارن و عمر طولانی میکنن، اینه که بتونن با تغییر نیازمندیها سازگار بشن و در عین حال نگهداری سادهای داشته باشن. وقتی اصول کدنویسی تمیز (Clean Code) رو رعایت کنیم، کدهامون خواناتر میشن؛ و این خوانایی خیلی مهمه چون واقعیت اینه که بخش عمده زمان یک برنامهنویس صرف خواندن کد میشه، نه نوشتن اون.
اینجا ۱۰ نکته سریع آوردم که بهت کمک میکنه کدی تمیزتر و حرفهایتر بنویسی.
۱. متدها رو کوتاه نگه دار — ترجیحاً زیر ۱۰ خط
سعی کن متدها بیشتر از ۱۰ خط نشه. متدهای کوتاه هم راحتتر خونده میشن، هم سادهتر تست و نگهداری میشن. هر وقت دیدی یک متد زیادی بزرگ شده، بهترین کار اینه که اون رو به چند متد کوچیکتر تقسیم کنی؛ متدهایی که هر کدوم یک وظیفه مشخص رو انجام بدن. یه نشونه خوب برای فهمیدن اینکه متدت زیادی بزرگ شده اینه که نتونی براش یه اسم کوتاه و دقیق پیدا کنی. وقتی اسمگذاری برات سخت میشه، یعنی احتمالا متدت داره چندین کار رو همزمان انجام میده و باید خرد بشه.
/ Original double singlePrice = product.getSinglePrice(); double taxRate = 0.07; double discount = 0.0; Customer customer = customerRepository.findById(customerId); if (customer.isSilver()) { if (customer.getYearsAsCustomer() > 5) { double totalDiscount = discount + bulkDiscount + loyaltyDiscount; double discountedPrice = totalWithTax - (totalWithTax * totalDiscount); return finalPrice; |
// After Refactoring double baseTotal = calculateBaseTotal(product, quantity); return roundToTwoDecimalPlaces(discountedPrice); private double calculateBaseTotal(Product product, int quantity) { private double applyTax(double baseTotal) { private double calculateTotalDiscount(Customer customer, int quantity) { return Math.min(totalDiscount, 0.30); private double calculateTierDiscount(Customer customer, int quantity) { if (customer.isSilver()) { return discount + bulkDiscount; private double calculateLoyaltyDiscount(Customer customer) { private double applyDiscount(double total, double discountRate) { private double roundToTwoDecimalPlaces(double value) { |
۲. کلاسها رو کوتاه نگه دار — ترجیحاً زیر ۲۰۰ خط
این نکته تقریباً واضحه. وقتی یک کلاس زیر ۲۰۰ خط باشه، معمولاً داری یکی از اصول مهم SOLID یعنی Single Responsibility رو رعایت میکنی. کلاسهای کوچکتر چندتا مزیت خیلی مهم دارن:
۳. تعداد متدهای عمومی رو به یک یا دو تا محدود کن
وقتی یک کلاس فقط برای انجام یک کار مشخص طراحی شده (طبق اصل Single Responsibility)، معمولاً نیازی نداره چندین متد عمومی داشته باشه. اگه بیشتر از یک متد پابلیک تعریف میکنی، باید دلیل منطقی پشتش باشه؛ مثلاً وقتی داری متدها رو Overload میکنی تا استفاده از کلاس برای Caller سادهتر بشه. مهم اینه که این کار رو آگاهانه انجام بدی، نه از روی عادت.
۴. از کامنتگذاری زیاد خودداری کن
در بیشتر مواقع کامنتها رو میشه با نامگذاری درست متدها جایگزین کرد. بذار کدت خودش حرف بزنه. اگه اسم متدها و کلاسهات واضح و گویا باشه، نیاز به توضیح اضافه توی کامنتها از بین میره.
// With Comments // Check if the product has a valid name // Check if the product price is greater than zero // Check if the product category is valid // Check if the product is active private boolean isValidCategory(String category) { |
// Without comments private void ensureProductIsNotNull(Product product) { private void ensureProductHasName(Product product) { private void ensurePriceIsPositive(Product product) { private void ensureCategoryIsValid(Product product) { private void ensureProductIsActive(Product product) { private boolean isValidCategory(String category) { |
5. ترجیح بده فقط یک Return داشته باشی
وجود چندین دستور return همیشه مشکلساز نیست، اما میتونه باعث بروز خطا بشه؛ مخصوصاً وقتی که تستها کامل و پوششدهی خوبی نداشته باشن. داشتن یک نقطه خروجی مشخص باعث میشه منطق شرطی (branching logic) توی کدت شفافتر بشه و قبل از انتشار راحتتر فرصت ریفکتور کردن داشته باشی.
// With multiple returns if (customer.isGold()) { if (customer.isSilver()) { return 0.0; کد بعدی //With single return if (customer.isPlatinum()) { return discount; |
6. از final برای متغیرها و پارامترها استفاده کن
در برنامههای مدرن، بهخصوص وقتی با عملیات بیتمحور حساس به عملکرد سروکار نداری، بهتره متغیرها و پارامترها رو final اعلام کنی. وقتی یک مقدار بهش اختصاص داده شد، دیگه نباید تغییر کنه. این کار باعث میشه اسم متغیر با هدفش همخوانی داشته باشه و احتمال اشتباه کمتر بشه.
البته گاهی متغیرها باید تغییر کنن (مثل همون چیزی که اسمشون نشون میده)، اما این موارد باید استثنا باشن، نه قاعده.
۷. کلاسهای Utility بدون Attribute
این نکته خودش واضحه. اگه به یک کلاس Utility ویژگی (attribute) اضافه میکنی، دیگه اون کلاس Utility محسوب نمیشه. کلاسهای Utility باید فقط شامل عملیات استاتیک باشن که روی پارامترهایی که دریافت میکنن کار میکنن، مثل متدهای دستکاری رشتهها (toLowerCase، isEmpty) که تو خیلی از کتابخونهها هستن.
۸. کلاسهای Utility رو به کلاسهای Instantiable منتقل کن
اگه چند کلاس Utility داری، یا یک کلاس Utility با متدهای زیاد، ممکنه وقتش رسیده باشه بعضی متدها یا حتی کل کلاس رو به کلاسهای معمولی قابل نمونهسازی (instantiable) منتقل کنی. این روش نگهداری کد رو بهتر میکنه، تست واحد (unit testing) رو راحتتر میکنه، امکان Dependency Injection رو فراهم میکنه و با اصول طراحی شیءگرای SOLID همخوانی داره.
۹. پیچیدگی سایکلوماتیک (Cyclomatic Complexity) رو زیر ۵ نگه دار
پیچیدگی سایکلوماتیک یکی از معیارهای مهم کیفیت کده. نگه داشتن این عدد زیر ۵ باعث میشه کدت راحتتر فهمیده، تست و نگهداری بشه.
public String determineAccessLevel(User user, Resource resource) { if (!user.isActive()) { if (user.isAdmin()) { return "DENIED"; |
برای کاهش پیچیدگی، کد را به متدهای با نام مناسب تقسیم کن
برای کاهش پیچیدگی، بخشهای مختلف کد رو به متدهای کوچک و با اسمهای واضح و گویا تقسیم کن. این کار هم خوانایی منطق کد رو بالا میبره و هم باعث میشه ساختار برنامه ماژولار باشه، یعنی هر بخش وظیفه مشخص خودش رو داشته باشه و تغییر یا تستش راحتتر باشه.
public String determineAccessLevel(User user, Resource resource) { if (isInvalid(user, resource)) { return accessLevel; private boolean isInvalid(User user, Resource resource) { private boolean isAdmin(User user) { private boolean isManagerAccess(User user, Resource resource) { private boolean isEmployee(User user) { private String getEmployeeAccessLevel(User user, Resource resource) { |
10. به جای Constants از Enums استفاده کن
استفاده از Enums به جای Constants چند مزیت مهم داره:
ایمنی نوع (Type safety): Enums در زمان کامپایل بررسی میشن و از اختصاص دادن مقادیر اشتباه جلوگیری میکنن.
محدودهبندی مقادیر (Scoped values): مقادیر Enum فقط در همون نوع Enum معتبر هستن و باعث نمیشن فضای نام جهانی آلوده بشه.
قابلیت توسعه (Extensibility): Enums میتونن فیلد، سازنده و متد داشته باشن و رفتارهای پیچیدهتر مثل toString() یا fromString() رو ارائه بدن.
نگهداری آسان (Maintainability): اضافه کردن یا تغییر مقادیر Enum امنتر و واضحتر از ویرایش String Constants هست.
هماهنگی با ابزارها (Tool integration): Enums به خوبی با قابلیتهای IDE مثل Autocomplete و Refactoring کار میکنن و با فریمورکهایی مثل Jackson یا JPA هم به راحتی ادغام میشن.
جلوگیری از استفاده نادرست (Prevents misuse): برخلاف Interface Constants، نمیتونی مقادیر Enumهای غیرمرتبط رو با هم قاطی کنی یا ازشون نمونه بسازی.
بستن *نام و نام خانوادگی * پست الکترونیک * متن پیام |
دوره های آموزشی برنامه نویسی
انجام پروژه های برنامه نویسی
تدریس خصوصی برنامه نویسی
بیش از 7 سال از فعالیت جاواپرو میگذرد
جاواپرو دارای مجوز نشر دیجیتال از وزارت فرهنگ و ارشاد اسلامی است
جهت ارتباط مستقیم با جاواپرو در واتساپ و تلگرام :
09301904690