2013-04-02 47 views
8

Một câu hỏi tương tự như câu hỏi này đã được hỏi trước đây, nhưng tôi yêu cầu cụ thể về việc sử dụng bố cục như một sự thay thế cho việc sử dụng các mixin mô-đun.Khi nào chúng ta sử dụng mô-đun ruby ​​và sử dụng thành phần lớp học?

class Helper 
    def do_somthing 
    end 
end 

Nếu tôi cần 'sử dụng' một lớp nhưng không kế thừa, tôi chỉ cần soạn và sử dụng nó.

class MyStuff 
    def initialize 
    helper = Helper.new 
    helper.do_something 
    end 
end 

Tại sao tôi muốn tạo một module cho việc này:

module Helper 
    def do_something 
    end 
end 

class MyStuff 
    include Helper 
end 

Sự khác biệt duy nhất tôi thấy là có wont được nhiều Helper đối tượng nằm xung quanh nếu tôi sử dụng mô-đun. Nhưng tôi không thấy bất cứ điều gì với nhiều đối tượng nằm xung quanh vs đối tượng nhỏ hơn.

Hơn nữa, tôi không biết liệu tôi có cần phân lớp nó trong tương lai hay không. Vậy làm cách nào để quyết định xem người dùng thư viện của tôi có muốn sử dụng mixin mô-đun hay muốn sử dụng bố cục?

+1

'require' không phải là những gì bạn cần ở đây. Bạn cần 'include'. – Linuxios

+0

thnx. cố định rằng – codeObserver

+0

Chắc chắn. Vui mừng được giúp đỡ. – Linuxios

Trả lời

14

Khi mối quan hệ giữa Helper và lớp MyStuff là một trong các quyền sở hữu, hãy sử dụng thành phần. Điều này được gọi là mối quan hệ "có-a". Ví dụ: giả sử bạn có lớp học Person và lớp học Car.Bạn sẽ sử dụng thành phần vì một người có một chiếc xe:

class Person 
    def initialize 
    @car = Car.new 
    end 
end 

class Car 
    def accelerate 
    # implementation 
    end 
end 

Khi Helper"hành vi như"MyStuff, sử dụng một mixin mô-đun. Helper, trong trường hợp này, có vai trò của MyStuff. Đây là một chút khác biệt so với mối quan hệ "is-a" "là-a", điều này có nghĩa là bạn nên sử dụng thừa kế truyền thống. Ví dụ: giả sử chúng ta có một lớp Person và mô-đun Sleeper. Một người có vai trò của một người ngủ đôi khi, nhưng các đối tượng khác cũng vậy - các trường hợp của Dog, Frog hoặc thậm chí có thể là Computer. Mỗi lớp khác đại diện cho cái gì đó có thể đi ngủ.

module Sleeper 
    def go_to_sleep 
    # implementation 
    end 
end 

class Person 
    include Sleeper 
end 

class Computer 
    include Sleeper 
end 

Sandi Metz thực Object-Oriented Design in Ruby là một tuyệt vời nguồn lực cho các chủ đề này.

0

Mô-đun mixin giống với nhiều thừa kế hơn, vì vậy hãy tuân theo quy tắc thừa kế thường lệ so với thành phần - là-a hoặc có-a. Nhân tiện, nó là include Helper, không phải require 'Helper'.

0

Có một vài điều tôi có thể chia sẻ:

  • Trong trường hợp bạn cần phải chia sẻ những hành vi phổ biến ở các lớp học khác nhau và mô-đun, bạn nên làm cho nó thành các module để sau này bạn có thể chỉ include các module bất cứ nơi nào bạn thích. Nó cũng sẽ giúp thử nghiệm vì nó đã DRY.

  • Trong trường hợp có trách nhiệm, bạn có thể biến nó thành mô-đun mới để hiểu rõ và cải thiện khả năng đọc của codebase. Nó sẽ giúp giảm kích thước của các lớp học chính của bạn mà nên được dễ dàng để làm theo và duy trì.

Một điều bạn có thể nhận thấy rằng include thêm chức năng để instance của bạn, nơi extend làm cho Class riêng của mình.

1

Đó là vấn đề “Duck Typing”. Nếu bạn muốn lớp học của bạn cư xử như một số Helper, bạn hãy include. Cho dù bạn là hành vi encapsulateHelper, lựa chọn đúng là require.

Trộn Enumerable trong, bạn cung cấp cho lớp của bạn tải trọng lớn các phương pháp bằng cách triển khai phương thức each chỉ. Gói Array bạn có thể ẩn lặp lại từ những người khác và sử dụng nó để chỉ giữ dữ liệu của bạn. Và ngược lại.

+0

Bạn có thể giải thích chút không? * 'bằng cách thực hiện chỉ có mỗi phương thức' * –

+1

Lớp của bạn chỉ thực hiện phương thức ** duy nhất ** (' mỗi') và trộn 'Enumerable' để sinh ra tất cả các thú vui của… hhmm… iterationing. – mudasobwa

+0

xấu của tôi! đã không nhận được bạn –

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