【问题标题】:Elegant way for instantiating one of a collection of objects based on a parameter?基于参数实例化一组对象的优雅方式?
【发布时间】:2016-02-23 21:22:14
【问题描述】:

我有一个表示 alert 的 JSON 字符串,它传递给我的控制器...... JSON 字符串中的一个参数是 alert 的类型。 IE。一个恐慌alert,一个仪器alert,一个硬盘驱动器alert等等。

我的每个 alert 类型都有对象,它们扩展了一个基础 alert 类。

class base_alert
    ...
end

class panic_alert < base_alert
    ...
end

class hard_drive_alert < base_alert
    ...
end

class instrument_alert < base_alert
    ...
end

有没有一种优雅的方法可以根据传入 json 字符串的参数有条件地实例化对象?

即如果 json 参数用于紧急警报,控制器将收到此信息并实例化紧急 alert 类。

我真的不想要一个巨大的 ifswitch 声明。

【问题讨论】:

  • 当你说“我的每个alert 类型都有对象扩展一个基alert 类”时,你是什么意思?您的问题应该包括您目前编写的相关代码。
  • json alert 字符串的名字和类名是否匹配?
  • 为了清晰起见,我添加了一些代码。我希望它更清楚。如果还有什么我可以添加以帮助它更容易理解,请告诉我。
  • @Nabeel,不遗憾。它实际上是一个指示警报类型的数字。但是,如果在类名相同的情况下有一种优雅的方法可以做到这一点,我可以先通过一个对象文字给它赋予相同的类名。
  • 然后使用 case 语句,这可能是最简单的方法

标签: ruby-on-rails ruby oop


【解决方案1】:

您可以使用Object.const_get("class_name") 获取课程。如果它们不相似,您可以使它们相似或创建一个哈希常量来映射它们

即:

MAP = { 'alert_1' => 'hard_drive' }

Object.const_get(MAP['alert_1']).new
=> #<SomeClass:0x00000001fb2538>

【讨论】:

    【解决方案2】:

    如果您反对 switch 语句(这可能被认为是最理想的)并且您的警报被作为数字传递,您存储一个 ALERTS 常量并使用一些元编程来实例化正确的警报:

    # For example given an alert value a
    ALERTS = {
      1 => "panic",
      2 => "hard_drive",
      3 => "instrument"
    }
    
    alert = eval("#{ALERTS[a]}_alert.new")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-03
      • 2012-03-09
      • 2013-12-20
      • 2013-09-15
      • 1970-01-01
      相关资源
      最近更新 更多