تسلط بر کیفیت کد: به کارگیری اصول SOLID در سیستم پرداخت کتابخانه
این جامد اصول مجموعه ای از پنج قانون طراحی در برنامه نویسی شی گرا و مهندسی نرم افزار هستند. این اصول به شما راهنمایی میکند تا کدی بنویسید که نگهداری، تغییر و استحکام آن آسانتر باشد. در این پست وبلاگ، ما هر یک از این اصول SOLID را بررسی میکنیم و توضیح میدهیم که چه معنایی دارند و چگونه به شما کمک میکنند تا نرمافزار بهتری بنویسید.
اصل مسئولیت واحد (SRP)
• اصل مسئولیت واحد بیان می کند که یک کلاس باید تنها یک دلیل برای تغییر داشته باشد. به عبارت دیگر باید یک مسئولیت واحد داشته باشد. هنگامی که یک کلاس بیش از یک مسئولیت دارد، به شدت با هم مرتبط می شود و ایجاد تغییرات بدون تأثیر بر سایر قسمت های کد را به چالش می کشد.
• برای اعمال SRP، کد خود را به کلاسها یا ماژولهای کوچکتر و متمرکز تقسیم کنید که هر کدام وظیفهای را بر عهده دارند. این نه تنها کد شما را قابل نگهداری تر می کند، بلکه قابلیت استفاده مجدد آن را نیز افزایش می دهد.
• به عنوان مثال، فرض کنید یک داریم LibraryCheckout
کلاسی که هم مسئول بررسی کتاب ها و هم محاسبه هزینه های تأخیر است:
class LibraryCheckout {
public void checkOutBook(Book book) {
// Process book checkout
}
public double calculateLateFee(Book book) {
// Calculate late fee
return lateFee;
}
}
• برای پایبندی به SRP، می توانید مسئولیت ها را از هم جدا کنید:
class BookCheckout {
public void checkOutBook(Book book) {
// Process book checkout
}
}
class LateFeeCalculator {
public double calculateLateFee(Book book) {
// Calculate late fee
return lateFee;
}
}
اصل باز/بسته (OCP)
• اصل باز/بسته پیشنهاد می کند که نهادهای نرم افزار باید برای توسعه باز باشند اما برای اصلاح بسته شوند. این بدان معنی است که شما باید بتوانید ویژگی ها یا رفتارهای جدیدی را بدون تغییر کد موجود اضافه کنید.
• برای حفظ OCP، از وراثت، رابط ها و انتزاعات استفاده کنید تا بسط آسان را فعال کنید. این اجازه می دهد تا عملکردهای جدید از طریق کلاس ها یا رابط های جدید اضافه شود، بدون نیاز به تغییر در کد موجود.
• مثلاً اگر یک LibraryCheckout
کلاس برای چک کردن کتابها، و ما میخواهیم آن را برای مدیریت ویدئوهای اجارهای گسترش دهیم، میتوانیم یک کلاس جدید بدون تغییر کلاس موجود ایجاد کنیم:
class VideoRentalCheckout {
public void checkOutVideo(Video video) {
// Process video checkout
}
}
اصل جایگزینی لیسکوف (LSP)
• اصل جایگزینی Liskov بر رابطه بین یک کلاس پایه و کلاس های مشتق شده از آن تمرکز دارد. بیان می کند که اشیاء کلاس های مشتق شده باید بتوانند بدون تأثیر بر صحت برنامه، جایگزین اشیاء کلاس پایه شوند.
• برای نشان دادن LSP، بیایید یک کلاس پایه LibraryItem و کلاس های مشتق شده آن Book و DVD را در نظر بگیریم:
class LibraryItem {
public void checkOut() {
// Check out the library item
}
}
class Book extends LibraryItem {
private String isbn;
public void setIsbn(String isbn) {
this.isbn = isbn;
}
@Override
public void checkOut() {
// Check out the book
}
}
class DVD extends LibraryItem {
private String title;
public void setTitle(String title) {
this.title = title;
}
@Override
public void checkOut() {
// Check out the DVD
}
}
• ما باید بتوانیم یک شی DVD را در هر جایی که یک شی LibraryItem انتظار می رود جایگزین کنیم بدون اینکه بر رفتار برنامه تأثیر بگذاریم:
public class Library {
public void processCheckout(LibraryItem item) {
item.checkOut();
}
}
public class Main {
public static void main(String[] args) {
Library library = new Library();
Book book = new Book();
book.setIsbn("978-3-16-148410-0");
library.processCheckout(book); // Process checkout for a book
DVD dvd = new DVD();
dvd.setTitle("The Matrix");
library.processCheckout(dvd); // Process checkout for a DVD
}
}
اصل جداسازی رابط (ISP)
• اصل جداسازی رابط از ایجاد رابط های خاص و متمرکز بر مشتری به جای رابط های بزرگ و یکپارچه حمایت می کند. بیان می کند که هیچ مشتری نباید مجبور شود به روش هایی که استفاده نمی کند وابسته باشد.
• برای پیروی از ISP، رابط های متناسب با نیازهای خاص مشتریان طراحی کنید. این امر نیاز مشتریان به پیاده سازی روش های غیر ضروری را کاهش می دهد و در نتیجه کد منسجم تر و قابل نگهداری تر را به همراه دارد.
• مثلاً به جای عریض LibraryService
رابط:
interface LibraryService {
void checkOutBook();
void returnBook();
}
• برای هر نوع سرویس رابط های خاصی ایجاد کنید:
interface BookCheckoutService {
void checkOutBook();
}
interface BookReturnService {
void returnBook();
}
اصل وارونگی وابستگی (DIP)
• اصل وارونگی وابستگی جداسازی ماژولهای سطح بالا از ماژولهای سطح پایین را با پیشنهاد این که هر دو باید به انتزاعات و نه پیادهسازی عینی وابسته باشند، ترویج میکند. این جداسازی تغییر ماژولهای سطح پایین را بدون تأثیرگذاری بر ماژولهای سطح بالا آسانتر میکند.
• برای پیاده سازی DIP، از تزریق وابستگی، وارونگی کانتینرهای کنترل و انتزاعات برای جداسازی اجزای سطح بالا و سطح پایین استفاده کنید. این انعطاف پذیری را افزایش می دهد، تست را آسان می کند و کوپلینگ را کاهش می دهد.
• مثلاً به جای داشتن یک LibraryService
به طور مستقیم به ارائه دهندگان کتاب خاص بستگی دارد:
class LibraryService {
private BookProvider provider;
public LibraryService(BookProvider provider) {
this.provider = provider;
}
public void checkOutBook() {
// Use the provider to check out a book
}
}
• به انتزاعات بستگی دارد:
interface BookProvider {
void checkOutBook();
}
class LibraryBookProvider implements BookProvider {
public void checkOutBook() {
// Checkout a book from the library
}
}
class OnlineBookProvider implements BookProvider {
public void checkOutBook() {
// Checkout a book online
}
}
class LibraryService {
private BookProvider provider;
public LibraryService(BookProvider provider) {
this.provider = provider;
}
public void checkOutBook() {
provider.checkOutBook();
}
}
• این مثال ها نشان می دهد که چگونه به کارگیری اصول SOLID می تواند سیستم پرداخت کتابخانه را مدولارتر و توسعه پذیرتر کند.
نتیجه
• اصول SOLID یک چارچوب قوی برای نوشتن کد قابل نگهداری و توسعه ارائه می دهد. با رعایت این اصول، میتوانید نرمافزاری را توسعه دهید که قابل اطمینانتر، درک آسانتر و کمتر مستعد خطا باشد. در حالی که تسلط بر این اصول ممکن است نیاز به تمرین داشته باشد، مزایای آن از نظر کیفیت کد و قابلیت نگهداری قابل توجه است. اصول SOLID را برای پروژه نرمافزاری بعدی خود یا هنگام بازفرآوری کد موجود برای ایجاد نرمافزار بهتر و سازگارتر در ذهن داشته باشید.