Clean Code Ruby – Các đối tượng và cấu trúc dữ liệu, các lớp, RẮN

Tram Ho

Tiếp nối chuối series clean code ruby, kỳ này là phần nói về làm thế nào để clean Objects and Data Structures, Classes, SOLID. Mời các bạn đón đọc nhé

Objects and Data Structures

Sử dụng getters và setters

Sử dụng getters và setters để truy cập dữ liệu trên các đối tượng có thể tốt hơn là chỉ đơn giản là tìm kiếm một thuộc tính trên một đối tượng. Dưới đây là những lý do tại sao:

  • Khi bạn muốn làm nhiều hơn ngoài việc chỉ có một thuộc tính đối tượng, bạn không phải tìm kiếm và thay đổi mọi truy cập trong cơ sở mã của bạn.
  • Làm cho việc xác nhận đơn giản hơn.
  • Đóng gói các đại diện nội bộ.
  • Dễ dàng thêm ghi log và xử lý lỗi khi getting và setting.
  • Bạn có thể lười tải các thuộc tính của đối tượng, thì có thể lấy nó từ máy chủ.

Good:

Ngoài ra, nếu getters và setters của bạn xử lý hoàn toàn bình thường, bạn nên sử dụng attr_accessor để định nghĩa chúng. Điều này đặc biệt thuận tiện cho việc triển khai các đối tượng, giống như việc hiển thị dữ liệu cho các phần khác của hệ thống.

Good:

Tuy nhiên, bạn phải lưu ý rằng trong một số tình huống, sử dụng attr_accessor khiến code của bạn bốc mùi, hãy đọc thêm tại đây.

Classes

Tránh Fluent interface

Fluent interface là một API hướng đối tượng nhằm cải thiện khả năng đọc mã nguồn bằng cách sử dụng chuỗi phương thức..

Mặc dù có thể trong một số trường hợp, các đối tượng xây dựng thường xuyên, trong đó mẫu này làm giảm tính dài dòng của mã (ví dụ: các truy vấn ActiveRecord), thường thì nó có chi phí:

Để biết thêm thông tin, bạn có thể đọc toàn bộ bài đăng trên blog về chủ đề này được viết bởi Marco Pivetta.

Bad:

Good:

Thích các thành phần hơn thừa kế

Như đã nêu trong cuốn sách nổi tiếng Mẫu thiết kế của Gang of Four, bạn nên thích sáng tác hơn là kế thừa nơi bạn có thể. Có rất nhiều lý do tốt để sử dụng thừa kế và rất nhiều lý do tốt để sử dụng thành phần. Điểm chính của câu châm ngôn này là nếu tâm trí của bạn theo bản năng đi theo sự kế thừa, hãy thử nghĩ xem liệu bố cục có thể mô hình hóa vấn đề của bạn tốt hơn không. Trong một số trường hợp, nó có thể.

Sau đó, bạn có thể tự hỏi, “khi nào tôi nên sử dụng thừa kế?” Nó phụ thuộc vào vấn đề của bạn, nhưng đây là một danh sách hợp lý khi kế thừa có ý nghĩa hơn thành phần:

  • Các class của bạn đại diện cho mối quan hệ “is-a” chứ không phải mối quan hệ “has-a” (Human->Animal vs. User->UserDetails).
  • Bạn có thể sử dụng lại mã từ các lớp cơ sở (Con người có thể di chuyển như tất cả các loài động vật).
  • Bạn muốn thực hiện các thay đổi cho các lớp con bằng cách thay đổi một lớp cơ sở. (Thay đổi chi phí calo của tất cả các động vật khi chúng di chuyển).

Bad:

Good:

SOLID

Nguyên tắc đơn nhiệm (SRP)

Như đã nêu trong Clean Code, “Không bao giờ nên có nhiều hơn một lý do để một lớp thay đổi”. Thật hấp dẫn khi đóng gói một lớp học với rất nhiều chức năng, như khi bạn chỉ có thể mang theo một chiếc vali trên chuyến bay của mình. Vấn đề với điều này là lớp của bạn sẽ không gắn kết về mặt khái niệm và điều đó sẽ cho nó nhiều lý do để thay đổi. Giảm thiểu số lần bạn cần thay đổi một lớp là rất quan trọng vì nếu có quá nhiều chức năng trong một lớp, khi bạn sửa đổi một phần của nó, có thể làm ảnh hưởng đến các mô-đun phụ thuộc khác trong cơ sở mã của bạn.

Bad:

Good:

Nguyên tắc mở / đóng (OCP)

Như Bertrand Meyer đã nêu ra, “các thực thể phần mềm (lớp, mô-đun, hàm, v.v.) nên được mở để mở rộng, nhưng đóng để sửa đổi.” Điều đó có nghĩa là gì? Nguyên tắc này về cơ bản nói rằng bạn nên cho phép người dùng thêm các chức năng mới mà không thay đổi mã hiện có.

Bad:

Good:

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

Đây là một thuật ngữ đáng sợ cho một khái niệm rất đơn giản. Nó được định nghĩa chính thức là “Nếu S là một kiểu con của T, thì các đối tượng thuộc loại T có thể được thay thế bằng các đối tượng loại S (nghĩa là các đối tượng loại S có thể thay thế các đối tượng thuộc loại T) mà không làm thay đổi bất kỳ thuộc tính mong muốn nào của chương trình đó (tính đúng đắn, nhiệm vụ được thực hiện, v.v.). ” Đó là một định nghĩa thậm chí còn đáng sợ hơn.

Giải thích tốt nhất cho điều này là nếu bạn có một lớp cha và một lớp con, thì lớp cơ sở luôn có thể được thay thế bởi lớp con mà không nhận được kết quả không chính xác. Điều này có thể vẫn còn gây nhầm lẫn, vì vậy hãy xem ví dụ về Hình chữ nhật vuông cổ điển. Về mặt toán học, hình vuông là một hình chữ nhật, nhưng nếu bạn mô hình hóa nó bằng cách sử dụng mối quan hệ “is-a” thông qua thừa kế, bạn sẽ nhanh chóng gặp rắc rối.

Bad:

Good:

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

Ruby không có giao diện nên nguyên tắc này không áp dụng nghiêm ngặt như các ngôn ngữ khác. Tuy nhiên, nó quan trọng và phù hợp ngay cả với hệ thống thiếu loại của Ruby.

ISP tuyên bố rằng “Khách hàng không nên bị buộc phải phụ thuộc vào các giao diện mà họ không sử dụng.”

Khi một máy khách phụ thuộc vào một lớp có chứa các giao diện mà máy khách không sử dụng, nhưng các máy khách khác sử dụng, thì máy khách đó sẽ bị ảnh hưởng bởi những thay đổi mà các máy khách khác thay đổi đối với lớp đó.

Bạn có thể tham khảo ở ví dụ sau đây

Bad:

Good:

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

Nguyên tắc này nêu hai điều thiết yếu:

  • Các mô-đun cấp cao không nên phụ thuộc vào các mô-đun cấp thấp. Cả hai nên phụ thuộc vào trừu tượng.
  • Trừu tượng không nên phụ thuộc vào chi tiết. Chi tiết nên phụ thuộc vào trừu tượng.

Nói một cách đơn giản, DIP giữ cho các mô-đun cấp cao không biết chi tiết về các mô-đun cấp thấp và thiết lập chúng. Một lợi ích rất lớn của việc này là nó làm giảm sự khớp nối giữa các mô-đun. Khớp nối là một mô hình phát triển rất tệ vì nó làm cho mã của bạn khó tái cấu trúc.

Như đã nói ở trên, Ruby không có giao diện nên các khái niệm trừu tượng phụ thuộc vào các hợp đồng ngầm. Điều đó có nghĩa là, các phương thức và thuộc tính mà một đối tượng / lớp tiếp xúc với một đối tượng / lớp khác. Trong ví dụ dưới đây, hợp đồng ngầm định là bất kỳ mô-đun Yêu cầu nào cho InventoryTracker sẽ có phương thức request_items.

Bad:

Good:

Link Tham khảo

https://github.com/uohzxela/clean-code-ruby#objects-and-data-structures
https://github.com/uohzxela/clean-code-ruby#classes
https://github.com/uohzxela/clean-code-ruby#solid

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo