2015-06-11 184 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中模塊和類之間的區別。 –