【问题标题】:Converting data structures to other data structures将数据结构转换为其他数据结构
【发布时间】:2015-06-11 21:51:41
【问题描述】:

我经常需要将某种数据转换成其他数据(通常是字符串、数组和散列)。例如:

  • 输入:"a;simple;list"
  • expected_output: [ { content: "a", length: 1 }, { content: "simple", length: 6 }, { content: "list", length: 4 } ]

这可以通过以下方式完成:

input.split(";").map{|s| { content: s, length: s.size } }

但我想在不同的地方使用转换。所以我需要提供封装的逻辑来实现和重用这一点。三种方式浮现在脑海中:

  1. 使用辅助方法(将单个方法放入模块中):

    module Converter
      extend self
      def convert(input)
        input.split(";").map{|s| { content: s, length: s.size } }
      end
    end
    
    module Caller
      Converter.convert(input)
    end
    
  2. 使用带参数的专用类:

    class Converter
      def initialize(input)
        @input = input
      end
      def convert
        @input.split(";").map{|s| { content: s, length: s.size } }
      end
    end
    
    module Caller
      Converter.new(input).convert
    end
    
  3. 使用改进,使用猴子补丁在数据对象上创建一个方法,但让调用者决定是否应该包含它。

    module Converter  
      refine String do
        def convert
          self.split(";").map{|s| { content: s, length: s.size } }
        end
      end
    end
    
    module Caller
      using Converter
      input.convert
    end
    

我对其中任何一个都不满意,但第三个选项似乎是最干净的,因为如果您处理自定义对象,通常会这样做。但它也感觉不对,因为它是猴子修补光。你有什么想法?

【问题讨论】:

  • 第三个选项基本上就是打算如何使用细化。
  • 这些都不会给你expected_output
  • 你说得对,我把expected_output键都改成了符号,现在应该是对的

标签: ruby oop coding-style data-conversion


【解决方案1】:

很高兴您从 OO 的角度来处理这个问题。

我喜欢你的第二个建议的变体,有一点不同——使用一个对象,但不要实例化它。

class StringConverter
  def self.to_size_hash(string)
    string.split(';').map { |s| { content: s, length: s.size } }
  end
end


2.2.2 :001 > StringConverter.to_size_hash "a;simple;list"
 => [{:content=>"a", :length=>1}, {:content=>"simple", :length=>6}, {:content=>"list", :length=>4}]

只要这个类只做一件事,一次,我想不出一个很好的理由将它保存在内存中。

这种方法的好处是您将逻辑封装在 StringConverter 类中,无需编写另一个模块(您问题中的第一个选项),或更改 String 类的预期行为(第三个选项)。这是一个专门用于这种转换的类,您可以在任何需要的地方使用它。

【讨论】:

  • 使用类方法而不是模块函数有什么好处?
  • 在这种情况下,我认为没有太大区别,只是个人喜好。我主要是建议一个专门的类(或模块)来避免改进。这样做会保留String 的行为。 Here's 很好地概述了 Ruby 中模块和类之间的区别。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 2017-11-26
  • 2021-10-26
  • 1970-01-01
相关资源
最近更新 更多