Ruby require循环

Ruby require循环,ruby,decorator,Ruby,Decorator,我有以下代码(简化): decorator.rb require 'decoratable' class Decorator < SimpleDelegator include Decoratable end require 'decorator_builder' module Decoratable def decorate(*decorators) decorators.inject(DecoratorBuilder.new(self)) do |builder,

我有以下代码(简化):

decorator.rb

require 'decoratable'

class Decorator < SimpleDelegator
  include Decoratable
end
require 'decorator_builder'

module Decoratable
  def decorate(*decorators)
    decorators.inject(DecoratorBuilder.new(self)) do |builder, decorator|
      builder.public_send(decorator)
    end.build
  end
end
require 'rare_decorator'

class DecoratorBuilder

  def initialize(card)
    @card = card
    @decorators = []
  end

  def rare
    @decorators << ->(card) { RareDecorator.new(card) }
    self
  end

  def build
    @decorators.inject(@card) do |card, decorator|
      decorator.call(card)
    end
  end

end
require 'decorator'

class RareDecorator < Decorator
  # Stuff here
end
decorator\u builder.rb

require 'decoratable'

class Decorator < SimpleDelegator
  include Decoratable
end
require 'decorator_builder'

module Decoratable
  def decorate(*decorators)
    decorators.inject(DecoratorBuilder.new(self)) do |builder, decorator|
      builder.public_send(decorator)
    end.build
  end
end
require 'rare_decorator'

class DecoratorBuilder

  def initialize(card)
    @card = card
    @decorators = []
  end

  def rare
    @decorators << ->(card) { RareDecorator.new(card) }
    self
  end

  def build
    @decorators.inject(@card) do |card, decorator|
      decorator.call(card)
    end
  end

end
require 'decorator'

class RareDecorator < Decorator
  # Stuff here
end
需要“稀有装饰器”
类装饰生成器
def初始化(卡)
@卡片
@装饰器=[]
结束
def稀有
@装饰师(卡片){raredcorator.new(卡片)}
自己
结束
def构建
@装饰者。注入(@card)do | card,装饰者|
装饰工。电话(卡)
结束
结束
结束
稀有装饰师.rb

require 'decoratable'

class Decorator < SimpleDelegator
  include Decoratable
end
require 'decorator_builder'

module Decoratable
  def decorate(*decorators)
    decorators.inject(DecoratorBuilder.new(self)) do |builder, decorator|
      builder.public_send(decorator)
    end.build
  end
end
require 'rare_decorator'

class DecoratorBuilder

  def initialize(card)
    @card = card
    @decorators = []
  end

  def rare
    @decorators << ->(card) { RareDecorator.new(card) }
    self
  end

  def build
    @decorators.inject(@card) do |card, decorator|
      decorator.call(card)
    end
  end

end
require 'decorator'

class RareDecorator < Decorator
  # Stuff here
end
需要“decorator”
类稀有装饰器<装饰器
#这里的东西
结束
当我需要decorator.rb时,它会导致在声明decorator之前声明raredcorator,这是一个问题,因为raredcorator继承自decorator

一种可能的解决方案是拆分decorator.rb,如下所示:

class Decorator < SimpleDelegator; end

require 'decoratable'

class Decorator
  include Decoratable
end
class Decorator

但是,在文件中间声明依赖项似乎对我来说不是一个非常干净的解决方案。


有更好的解决方案吗?

不要在每个文件中指定要求,而是创建一个需要应用程序所有要求的文件。例如,将其称为
environment.rb

require 'decoratable'
require 'decorator'
require 'decorator_builder'
require 'rare_decorator'

您不必担心
decoratible
不知道
DecoratorBuilder
是什么,因为它在方法中使用,调用此方法时将执行常量检查。既然您稍后需要decorator,那么一切都会好起来。

为什么decorator需要decorable?这就是你问题的根源(意味着你有一个设计问题),因为我希望装饰师和被装饰的东西都包括可装饰的。然后也可以装饰装饰器,向装饰器链添加更多装饰器。如果decorators不包括decoratible,那么对已经装饰过的对象调用decorative将替换decorator,而不是添加它们。很抱歉,如果我使用了decoration:PI这个词,我同意这个设置表明了一个设计问题,这也是我发布它的部分原因,但是如果没有这个奇怪的依赖循环,我看不到任何其他方法来完成上面的操作。太好了,谢谢:)。我一直倾向于在每个文件中声明依赖项,但现在我看到了完全控制文件加载顺序的优势。这样做的缺点是在gem中打包装饰器行为要困难得多,因为gem的任何/所有使用者都需要类似的
环境.rb
文件(或需要您的)。循环依赖仍然存在于代码中,这暗示了糟糕的设计。我认为DecoratorBuilder和RaredCorator之间的IoC将打破这种循环依赖。因此DecoratorBuilder开始时不知道它可以构建的Decorator,然后RaredCorator在加载时向DecoratorBuilder注册它自己。这样,代码或者说,装饰根本不依赖于混凝土装饰师,这似乎是更好的设计。