2015-06-11 147 views
2

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

  • 输入:"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 
    

我有任何不满意他们的,但第三个选择似乎最干净的,因为这通常是如果你对付的自定义对象,你会做什么。但它也感觉不对,因为它是猴子修补灯。你怎么看?

+1

第三个选项基本上是如何使用精化。 –

+0

这些都不会给你'expected_output'。 – sawa

+0

你说得对,我把'expected_output'全部改为符号,现在应该是对的 – leifg

回答

1

从面向对象的角度来看,这很棒。

我喜欢你的第二个建议的变体,只有一个小差异 - 使用一个对象,但不要实例化它。

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类的预期行为(第三个选项)。这是一个专门为这种转变而设计的课程,您可以在任何需要它的地方使用它。

+1

使用类方法而不是模块函数有什么好处? – mbigras

+1

在这种情况下,我认为没有太大区别,只是个人偏好。我主要建议一个专门的类(或模块)来避免改进。这样做保留了'String'的行为。 [Here's](https://stackoverflow.com/questions/151505/difference-between-a-class-and-a-module)很好地概述了Ruby中模块和类之间的区别。 –