Private classes in Ruby
Tại sao private? Một trong những cách phổ biến nhất để làm cho một số đoạn code của bạn dễ hiểu hơn và rõ ràng hơn là trích xuất một lớp. Tuy nhiên, nhiều lần lớp này không dành cho việc sử dụng một cách public. Đó là một chi tiết thực hiện của một lớp lớn hơn. Nó không nên được sử dụng được bất ...
Tại sao private?
Một trong những cách phổ biến nhất để làm cho một số đoạn code của bạn dễ hiểu hơn và rõ ràng hơn là trích xuất một lớp. Tuy nhiên, nhiều lần lớp này không dành cho việc sử dụng một cách public. Đó là một chi tiết thực hiện của một lớp lớn hơn. Nó không nên được sử dụng được bất cứ ai khác, nhưng mô-đun trong đó đã được định nghĩa. Vậy làm thế nào để chúng ta che giấu được lớp học đó để những người khác không sử dụng? Đôi khi nó có ý nghĩa, để xác định các lớp riêng tư. Ví dụ nếu logic đặc biệt đã được di chuyển vào một lớp liên quan cho các lý do đóng gói. Sau đó, không cần phải rời khỏi lớp là công khai. Một lớp Product là một ví dụ hợp lý. Mỗi sản phẩm được đặc trưng bởi số serial cụ thể của nó. Tuy nhiên, lớp Sản phẩm không chịu trách nhiệm tạo ra số sê-ri. Nó là để đóng gói logic vào một lớp Serial riêng biệt. Thậm chí nhiều hơn, nếu số serial chứa logic thêm nữa:
class Product class Serial def initialize @date = Date.today end def code "#{@date}/#{object_id}" end end attr_reader :serial def initialize @serial = Serial.new end def code serial.code end end
Lớp Product có thể sử dụng Serial một cách tự do: Một Product tạo mới với Serrial
Product.new.code # => "2017-06-11/32713960"
Mặc dù lớp Serial có thể truy cập bên ngoài:
Product::Serial.new # => #<Product::Serial:0x00000002be1548 ... >
Sử dụng private_constant
class Product class Serial def initialize @date = Date.today end def code "#{@date}/#{object_id}" end end # explizit privat: private_constant :Serial attr_reader :serial def initialize @serial = Serial.new end def code serial.code end end
Lớp Serial được khai báo riêng bằng cách sử dụng Module # private_constant. Đó là lý do tại sao nó không thể được instantiated trực tiếp nữa:
Product::Serial.new # => NameError: private constant Product::Serial referenced
Vì vậy, Product là công khai mà bạn phơi bày cho các phần khác của hệ thống và Product :: Serial chỉ là một chi tiết thực hiện. Bạn cũng có thể không thử trực tiếp Product :: Serial trực tiếp, nhưng thông qua Product công khai mà khách hàng sẽ sử dụng.