我有一段 Ruby 代码可以归结为:
class Foo
attr_reader :a, :b, :c
def initialize
build_a
build_b
build_c
end
private
def build_a
# something complex that eventually results in @a = something
end
def build_b
# something complex that eventually results in @b = something
end
def build_c
# something complex that eventually results in @c = something
end
end
在initialize
方法中调用build_*
似乎有点多余。有没有更好的方法来写这个?我当然知道延迟加载模式:
class A
def a
@a ||= something_complex
end
end
但是,我需要这段代码是线程安全的,所以我不能在这里使用那个模式。
编辑:我对这段代码的主要关注是,我希望看到这样一个事实,即 build_a
应该在初始化后调用,而是写在 build_a
的定义中在 initialize
方法中。
最佳答案
那些回调将是测试和维护的真正痛苦。这个解决方案不是更好吗?:
class Foo
attr_reader :a, :b, :c
def initialize
# things that belong in initialize
end
def self.call # or any other name
new.build_things
end
def build_things
build_a
build_b
build_c
end
end
唯一的缺点是您将使用 Foo.call
而不是 Foo.new
。如果您不希望此类“感觉”像一个服务对象,我会继续将它包装在一个中,例如 FooBuilder
。这样您就可以避免回调,测试很容易,并且您的代码清晰易读。如果您想在初始化后build_things
,我认为这是最好的方法。
关于Ruby:改进复杂的初始化方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32038850/