Tình huống: Tôi có nhiều lớp mà mỗi biến phải giữ một biến với băm cấu hình; một băm khác nhau cho mỗi lớp nhưng giống nhau cho tất cả các phiên bản của một lớp.Ruby: Thừa kế mã hoạt động với các biến lớp
Lúc đầu, tôi đã cố gắng như thế này
class A
def self.init config
@@config = config
end
def config
@@config
end
end
class B < A; end
class C < A; end
Nhưng chẳng mấy chốc nhận thấy rằng nó sẽ không hoạt động theo cách đó vì @@ cấu hình được tổ chức trong bối cảnh của A, không B hoặc C, như sau:
B.init "bar"
p B.new.config # => "bar"
p C.new.config # => "bar" - which would be nil if B had it's own @@config
C.init "foo"
p B.new.config # => "foo" - which would still be "bar" if C had it's own @@config
p C.new.config # => "foo"
tôi nghĩ của việc sử dụng nó như thế này:
modules = [B, C]
modules.each do |m|
m.init(@config[m.name])
end
# ...
B.new # which should then have the correct config
Bây giờ, nó là rõ ràng với tôi lý do tại sao điều đó xảy ra, nhưng tôi không chắc chắn về thứ e lý do cho nó được như thế này.
Không thể nó hoạt động theo cách khác, giữ biến lớp trong ngữ cảnh của lớp con?
Điều tôi cũng thấy khó chịu là thực tế rằng bản thân luôn là lớp con ngay cả khi được gọi là 'trong' lớp cha. Từ đây, đầu tiên tôi dự kiến mã từ lớp cha là "được thực thi trong ngữ cảnh" của lớp con.
Một số chứng ngộ về điều này sẽ được đánh giá cao.
Mặt khác, tôi có thể phải chấp nhận nó hoạt động theo cách đó và tôi phải tìm cách khác để thực hiện việc này.
Có cách nào "meta" để thực hiện việc này không? (Tôi đã thử với class_variable_set, v.v. nhưng không có may mắn)
Hoặc có thể toàn bộ ý tưởng về phương pháp 'init' đó không đúng lúc đầu và có một số "mẫu" khác để làm điều này?
Tôi chỉ có thể làm cho @@ config một băm, giữ tất cả các cấu hình và luôn chọn đúng, nhưng tôi thấy rằng một chút khó xử .. (không phải là thừa kế ở đó để giải quyết loại vấn đề?;)
Tôi không thấy thiết kế này có vẻ như thế nào. Nó có vẻ như một điều đủ hợp lý để làm nói chung. – Chuck
Đó chính xác là những gì tôi cần biết, cảm ơn bạn rất nhiều! :) Không thực sự biết những gì khác để nói, nó là tất cả như vậy rõ ràng bây giờ. Phương pháp init được thiết kế để thiết lập nhiều biến, tôi đã nhận được ví dụ cấu hình để đơn giản. Nhưng bây giờ bạn đề cập đến nó, nó có lẽ vẫn còn sạch hơn với accessors;) Một lần nữa, cảm ơn rất nhiều! –
@Chuck: Ví dụ, có một phương thức cá thể ('A # config') không gọi phương thức cá thể cũng như truy cập trạng thái cá thể cũng không bị ghi đè. Đó có thể là một tạo tác của ví dụ được cắt xén, nó có thể là một thiết kế hợp pháp, nhưng, có lẽ, nó không phải. Ngoài ra, B và C kế thừa từ A, nhưng không ghi đè lên bất cứ điều gì, tuy nhiên, họ bằng cách nào đó dự kiến sẽ có hành vi khác nhau cả từ lẫn nhau và từ A, mặc dù tất cả chúng đều giống hệt nhau. Một lần nữa: có thể hợp lý, có thể không. Tất cả phụ thuộc vào bối cảnh, tất nhiên là quá nhỏ trong ví dụ này để đạt được bất kỳ kết luận hợp lý nào. –