2010-04-19 37 views
17

Tôi hiện đang làm việc thông qua sách Gregory Brown Ruby Best Practices. Ban đầu, anh ta đang nói về việc tái cấu trúc một số chức năng từ các phương thức trợ giúp trên một lớp liên quan, đến một số phương thức trên mô đun, sau đó có mô-đun extend self.Khi nào cần sử dụng một mô-đun và khi nào nên sử dụng một lớp học

Chưa từng thấy trước đó, sau một google nhanh chóng, phát hiện ra rằng extend self trên mô-đun cho phép các phương thức được xác định trên mô-đun nhìn thấy nhau, điều này có ý nghĩa.

Bây giờ, câu hỏi của tôi là khi bạn sẽ làm điều gì đó như thế này

module StyleParser 
    extend self 

    def process(text) 
    ... 
    end 

    def style_tag?(text) 
    ... 
    end 
end 

và sau đó đề cập đến nó trong các thử nghiệm với

@parser = Prawn::Document::Text::StyleParser 

như trái ngược với một cái gì đó như thế này?

class StyleParser 

    def self.process(text) 
    ... 
    end 

    def self.style_tag?(text) 
    ... 
    end 
end 

là nó để bạn có thể sử dụng làm mixin? hoặc có lý do nào khác mà tôi không thấy?

Trả lời

30

Lớp học nên được sử dụng cho chức năng yêu cầu khởi tạo hoặc cần theo dõi trạng thái. Một mô-đun có thể được sử dụng như một cách để trộn chức năng vào nhiều lớp, hoặc như một cách để cung cấp các tính năng một lần không cần phải được khởi tạo hoặc theo dõi trạng thái. Một phương thức lớp cũng có thể được sử dụng cho phương thức sau.

Với ý nghĩ đó, tôi nghĩ sự khác biệt nằm trong việc bạn có thực sự cần một lớp hay không. Một phương thức lớp có vẻ phù hợp hơn khi bạn có một lớp hiện có cần một số chức năng đơn. Nếu những gì bạn đang làm chỉ bao gồm các phương thức singleton, nó có ý nghĩa hơn khi thực hiện nó như một mô-đun và truy cập nó thông qua mô đun trực tiếp.

+1

Chính xác những gì tôi đang tìm kiếm :-) –

-2

Nếu đó là điều bạn muốn khởi tạo, hãy sử dụng lớp học. Phần còn lại của câu hỏi của bạn cần thêm ngữ cảnh để có ý nghĩa.

3

Trong trường hợp cụ thể này, tôi có lẽ sẽ không phải là một lớp hay một mô-đun.

Lớp học là nhà máy cho các đối tượng (lưu ý số nhiều). Nếu bạn không muốn tạo nhiều phiên bản của lớp, không cần nó tồn tại.

Mô-đun là vùng chứa cho các phương thức, được chia sẻ giữa nhiều đối tượng. Nếu bạn không kết hợp các mô-đun vào nhiều đối tượng, không cần nó tồn tại.

Trong trường hợp này, có vẻ như bạn chỉ muốn một đối tượng. Vì vậy, sử dụng một trong:

def (StyleParser = Object.new).process(text) 
    ... 
end 

def StyleParser.style_tag?(text) 
    ... 
end 

Hoặc cách khác:

class << (StyleParser = Object.new) 
    def process(text) 
    ... 
    end 

    def style_tag?(text) 
    ... 
    end 
end 

Nhưng khi @Azeem đã viết: cho một quyết định đúng đắn, bạn cần thêm ngữ cảnh. Tôi không đủ quen thuộc với những người bên trong của Prawn để biết tại sao Gregory lại đưa ra quyết định cụ thể đó.

Các vấn đề liên quan