[英]When do we use ruby module vs using class composition?
之前已經提出過與此類似的問題,但我特別要求使用組合作為使用模塊mixins的替代方法。
class Helper
def do_somthing
end
end
如果我需要“使用”一個類而不是繼承它,我只需編寫並使用它。
class MyStuff
def initialize
helper = Helper.new
helper.do_something
end
end
為什么我要為此創建一個模塊:
module Helper
def do_something
end
end
class MyStuff
include Helper
end
我看到的唯一區別是,如果我使用模塊,那么就不會有很多Helper
對象。 但是我沒有看到任何東西,周圍有更多物體,而不是更大的物體。
而且,我不知道將來是否需要將其子類化。 那么我該如何判斷我的庫的用戶是想要使用模塊mixin,還是想要使用合成?
當Helper
和MyStuff
類之間的關系是所有權之間的關系時,請使用組合 。 這被稱為“has-a”關系。 例如,假設你有Person
類和Car
類。 你會使用作文,因為一個人有車:
class Person
def initialize
@car = Car.new
end
end
class Car
def accelerate
# implementation
end
end
當Helper
“充當” MyStuff
,請使用模塊mixin 。 在這種情況下, Helper
扮演 MyStuff
的角色 。 這與“is-a”關系略有不同,這意味着您應該使用傳統繼承 。 例如,假設我們有一個Person
類和一個Sleeper
模塊。 一個人有時扮演一個睡眠者的角色,但其他物體也是如此 - Dog
, Frog
甚至Computer
實例。 其他每一類都代表着可以入睡的東西。
module Sleeper
def go_to_sleep
# implementation
end
end
class Person
include Sleeper
end
class Computer
include Sleeper
end
這是“ 鴨子打字 ”的問題。 如果您希望您的班級表現得像Helper
,那么您可以include
。 無論您是要封裝 Helper
行為,都require
正確的選擇。
混合Enumerable
,通過僅實現each
方法,為您的類提供大量方法。 包裝Array
您可以隱藏其他人的迭代並使用它來保存您的數據。 反之亦然。
模塊mixin更像是多重繼承,因此遵循通常的繼承與組合規則 - 是-a或has-a。 順便說一下,它include Helper
, require 'Helper'
。
我可以分享一些東西:
如果您需要在不同的類和模塊中共享常見行為,您應該將其轉換為模塊,以便以后可以將模塊include
在您喜歡的任何位置。 它也將有助於測試,因為它已經干了。
在責任的情況下,您可以將其轉換為新模塊,以便清楚地理解並提高代碼庫的可讀性。 這將有助於減少主要類的大小,這應該易於遵循和維護。
您可能會注意到的一件事include
為您的instance
添加功能,其中extend
對Class
本身。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.