Các nguyên tắc RẮC RẮN: Làm cho mã của bạn rõ ràng và dễ hiểu

Tram Ho

Khi viết mã, điều quan trọng là đảm bảo nó dễ đọc và dễ hiểu. Điều này đặc biệt đúng khi làm việc trong các dự án lớn với nhiều phần khác nhau. Một cách để đảm bảo mã của bạn dễ hiểu là tuân theo các nguyên tắc RẮN.

SOLID là viết tắt của năm nguyên tắc khác nhau:

  1. Nguyên tắc trách nhiệm duy nhất (SRP)
  2. Nguyên tắc Mở-Đóng (OCP)
  3. Nguyên tắc thay thế Liskov (LSP)
  4. Nguyên tắc phân tách giao diện (ISP)
  5. Nguyên tắc đảo ngược phụ thuộc (DIP)

Chúng ta hãy xem xét từng nguyên tắc một và xem chúng có thể giúp mã của bạn tốt hơn như thế nào.

Giải thích

Nguyên tắc trách nhiệm duy nhất (SRP)

Nguyên tắc Trách nhiệm Đơn lẻ (SRP) nói rằng mỗi phần mã của bạn chỉ nên có một công việc. Điều này có nghĩa là nếu bạn có một đoạn mã làm nhiều việc, bạn nên chia nó thành các phần nhỏ hơn, mỗi phần có nhiệm vụ riêng.

Ví dụ: hãy tưởng tượng bạn có một đoạn mã theo dõi số lần nhấp vào một nút và cũng hiển thị số lần nhấp trên màn hình. Theo SRP, mã này nên được chia thành hai phần riêng biệt: một phần theo dõi số lần nhấp và phần còn lại hiển thị số lần nhấp trên màn hình.

Nguyên tắc Mở-Đóng (OCP)

Nguyên tắc Open-Closed (OCP) nói rằng mã của bạn nên mở để mở rộng nhưng đóng để sửa đổi. Điều này có nghĩa là bạn có thể thêm các tính năng mới vào mã của mình mà không cần thay đổi mã hiện có.

Ví dụ, hãy tưởng tượng bạn có một chương trình có thể cộng hai số với nhau. Theo OCP, bạn sẽ có thể thêm một tính năng mới (chẳng hạn như trừ các số) mà không cần thay đổi mã hiện có để thêm số.

Nguyên tắc thay thế Liskov (LSP)

Nguyên tắc thay thế Liskov (LSP) nói rằng bạn sẽ có thể sử dụng một lớp con ở bất cứ nơi nào bạn muốn sử dụng lớp cha. Điều này có nghĩa là lớp con phải là phiên bản “tốt hơn” của lớp cha và không được phá vỡ bất kỳ mã nào sử dụng lớp cha.

Ví dụ, hãy tưởng tượng bạn có một lớp cha tên là “Animal” và một lớp con tên là “Dogs”. Theo LSP, bạn sẽ có thể sử dụng đối tượng “Chó” ở bất cứ đâu bạn sẽ sử dụng đối tượng “Động vật” và mã của bạn vẫn hoạt động bình thường.

Nguyên tắc phân tách giao diện (ISP)

Nguyên tắc Phân tách Giao diện (ISP) nói rằng bạn không nên ép buộc khách hàng triển khai các giao diện mà họ không sử dụng. Điều này có nghĩa là bạn nên tạo các giao diện nhỏ hơn cho các nhóm chức năng liên quan cụ thể.

Ví dụ: hãy tưởng tượng bạn có một giao diện tên là “Ô tô” có chức năng cho cả lái xe và bay. Theo ISP, nếu bạn có một lớp dành cho ô tô chỉ có thể lái, thì không nên buộc phải thực hiện các chức năng bay từ giao diện “Ô tô”.

Nguyên tắc đảo ngược phụ thuộc (DIP)

Nguyên tắc đảo ngược phụ thuộc (DIP) nói rằng các mô-đun cấp cao không nên phụ thuộc vào các mô-đun cấp thấp, nhưng cả hai nên phụ thuộc vào sự trừu tượng. Điều này có nghĩa là mã của bạn không nên phụ thuộc vào các lớp hoặc chức năng cụ thể, mà phải phụ thuộc vào các khái niệm trừu tượng.

Ví dụ: hãy tưởng tượng bạn có một lớp tên là “Xe hơi” phụ thuộc vào một lớp tên là “Động cơ”. Theo DIP, lớp “Xe hơi” không nên phụ thuộc vào lớp “Động cơ” cụ thể, mà phụ thuộc vào sự trừu tượng hóa động cơ là gì.

Trường hợp sử dụng

1. Quy trình thanh toán website thương mại điện tử

Giả sử chúng ta có một trang web thương mại điện tử nơi khách hàng có thể thêm các mặt hàng vào giỏ hàng của họ và sau đó chuyển đến trang thanh toán. Quá trình thanh toán bao gồm tính toán tổng chi phí của các mặt hàng, áp dụng bất kỳ giảm giá hoặc khuyến mãi nào, sau đó xử lý thanh toán.

Theo Nguyên tắc trách nhiệm duy nhất (SRP), chúng ta nên tách quy trình thanh toán thành các lớp khác nhau, mỗi lớp có trách nhiệm cụ thể của riêng mình. Ví dụ: chúng tôi có thể có lớp Giỏ hàng theo dõi các mặt hàng trong giỏ hàng, lớp Giảm giá áp dụng bất kỳ giảm giá hoặc khuyến mại nào và lớp Thanh toán xử lý quá trình thanh toán.

Trong ví dụ này, mỗi lớp có một trách nhiệm duy nhất: lớp Cart theo dõi các mặt hàng trong giỏ hàng, lớp Discounts áp dụng giảm giá, lớp Payment xử lý thanh toán và lớp Checkout điều phối quá trình. Điều này làm cho mã dễ bảo trì hơn và dễ hiểu hơn.

2. Ứng dụng thời tiết

Giả sử chúng ta có một ứng dụng thời tiết hiển thị nhiệt độ, độ ẩm và áp suất hiện tại cho một vị trí nhất định. Chúng tôi muốn thêm một tính năng mới hiển thị tốc độ và hướng gió.

Theo Nguyên tắc Đóng-Mở (OCP), chúng tôi có thể thêm tính năng mới này mà không cần sửa đổi mã hiện có hiển thị nhiệt độ, độ ẩm và áp suất.

Trong ví dụ này, lớp WeatherApp mở rộng bằng cách thêm lớp WindDisplay mới mà không sửa đổi lớp WeatherDisplay hiện có. Điều này cho phép chúng tôi thêm các tính năng mới vào ứng dụng mà không ảnh hưởng đến mã hiện có.

3. Nhân vật trong game

Giả sử chúng ta có một trò chơi có nhiều loại nhân vật khác nhau, mỗi loại có những khả năng riêng. Chúng tôi muốn thêm một loại nhân vật mới mà không phá vỡ cơ chế trò chơi hiện có.

Theo Nguyên tắc thay thế Liskov (LSP), chúng tôi sẽ có thể sử dụng lớp ký tự mới ở bất cứ nơi nào chúng tôi sẽ sử dụng lớp ký tự gốc và trò chơi vẫn hoạt động bình thường.

Trong ví dụ này, lớp Paladin là một lớp con của lớp Chiến binh và nó có khả năng chữa lành vết thương riêng, nhưng nó vẫn thực hiện chính xác phương thức di chuyển từ lớp cha, vì vậy nó có thể được sử dụng ở bất cứ đâu mà đối tượng Character được sử dụng. Điều này cho phép chúng tôi thêm các loại nhân vật mới mà không phá vỡ cơ chế trò chơi hiện có.

4. Ứng dụng trò chuyện

Giả sử chúng ta có một ứng dụng trò chuyện cho phép người dùng gửi tin nhắn và tệp. Chúng tôi muốn tách chức năng gửi tin nhắn và gửi tệp để khách hàng chỉ cần một trong hai tính năng không phải triển khai tính năng còn lại.

Theo Nguyên tắc phân tách giao diện (ISP), chúng ta nên tạo hai giao diện riêng biệt, một giao diện để gửi tin nhắn và một giao diện khác để gửi tệp.

Trong ví dụ này, lớp ChatClient chỉ triển khai giao diện MessageSender và không phải triển khai giao diện FileSender và lớp FileTransferClient chỉ triển khai giao diện FileSender và không phải triển khai giao diện MessageSender . Điều này cho phép khách hàng chỉ triển khai chức năng họ cần, đồng thời giữ cho mã rõ ràng và dễ hiểu.

5. Nền tảng truyền thông xã hội

Giả sử chúng ta có một nền tảng truyền thông xã hội cho phép người dùng đăng cập nhật văn bản và hình ảnh. Chúng tôi muốn thêm một tính năng mới cho phép người dùng đăng cập nhật video mà không thay đổi mã hiện tại để xử lý cập nhật văn bản và hình ảnh.

Theo Nguyên tắc đảo ngược phụ thuộc (DIP), chúng ta nên đảm bảo rằng mã để xử lý các bản cập nhật không phụ thuộc vào các lớp hoặc chức năng cụ thể, mà phụ thuộc vào các khái niệm trừu tượng.

Trong ví dụ này, lớp SocialMediaApp không phụ thuộc vào các lớp cụ thể để xử lý cập nhật văn bản, hình ảnh hoặc video, mà phụ thuộc vào khái niệm trừu tượng của giao diện Update . Điều này cho phép chúng tôi thêm các loại cập nhật mới (chẳng hạn như cập nhật video) mà không thay đổi mã hiện có để xử lý các cập nhật văn bản và hình ảnh.

Phần kết luận

Các nguyên tắc SOLID là một bộ hướng dẫn giúp các nhà phát triển viết mã rõ ràng, dễ bảo trì và dễ hiểu. Bằng cách tuân theo các nguyên tắc này, các nhà phát triển có thể đảm bảo rằng mã của họ dễ làm việc và có thể dễ dàng mở rộng hoặc sửa đổi trong tương lai. Các nguyên tắc SOLID là: Nguyên tắc trách nhiệm đơn (SRP), Nguyên tắc đóng mở (OCP), Nguyên tắc thay thế Liskov (LSP), Nguyên tắc phân tách giao diện (ISP) và Nguyên tắc đảo ngược phụ thuộc (DIP). Mỗi nguyên tắc đều có lời giải thích, ưu điểm và ví dụ sử dụng trong thế giới thực với các đoạn mã riêng. Điều quan trọng cần lưu ý là các nguyên tắc RẮN không phải là các quy tắc cứng và nhanh, mà là các hướng dẫn chung có thể được áp dụng theo các cách khác nhau, tùy thuộc vào dự án hoặc ứng dụng cụ thể.

Giới thiệu

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo