Ruby - 为每个包含的模块调用一个函数

时间:2014-11-28 22:05:04

标签: ruby mixins

我正在为Ruby项目进行XML导出,我正在寻找一种优雅的方法来实现它。此XML文件的目标是导出项目容器内的所有数据,并且有几个模型(大约20个)共享一些公共属性(例如名称和描述)。

目前,XML导出看起来很糟糕:

def export_project(p)
  @xml project {
     @xml.name p.name
     @xml.description p.description

     @xml.itemAs {
       p.item_as.each {|item_a|export_itemA(item_a)
     }

     @xml.itemBs {
       p.item_Bs.each {|item_B|export_itemB(item_b)
     }

     @xml.itemCs {
       p.item_cs.each {|item_c|export_itemC(item_c)
     }
    }
  end

  def export_itemA(a)
    @xml.itemA {
      @xml.name a.name
    }
  end

  def export_itemB(b)
    @xml.itemB {
      @xml.description b.description
    }
  end


  def export_itemC(c)
    @xml.itemC {
      @xml.name c.name
      @xml.description c.description 
    }
  end

这是非常丑陋的(好吧,它有4种类型可承受,但现实是480行混乱...)

我想要的是这样的(考虑到模型和导出器之间存在神奇的映射):

module Named
  def export
    @xml.name @context.name
  end
end

module Described
  def export
    @xml.description @context.description
  end
end

class ProjectExporter < ModelExporter
  include Named
  include Described

  def export
    @xml.project {
      super

     @xml.itemAs {
       export_items(p.item_as)
     }

     @xml.itemBs {
       export_items(p.item_Bs)
     }

     @xml.itemCs {
       export_items(p.item_cs)
     }
   }
end

class ItemAExporter < ModelExporter
  include Named

  def export
    @xml.itemA {
      super
    }
  end
end

class ItemBExporter < ModelExporter
  include Described

  def export
    @xml.itemB {
      super
    }
  end
end

class ItemCExporter < ModelExporter
  include Named
  include Described

  def export
    @xml.itemC {
      super
    }
  end
end

这种方法的问题是“super”只会调用其中一个模块的导出方法,而不是所有模块。

我很自信模块和超级方法不正确,但我找不到更合适的东西。有什么想法吗?

干杯谢谢, 文森特

0 个答案:

没有答案