2013-08-07 26 views
0

我想重構一些讀取csv文件的代碼。文件每一行中的第一個字符表示記錄類型:H =標題,I =信息,D =數據。每種記錄類型都有固定的不同數量的字段。我的程序使用FasterCSV從文件中讀取一行,然後使用case語句確定如何處理該行。重構代碼,導入一個csv文件有標題

 record_type = new_record[:record_type] 
    case record_type 
    when "H" 
    factory_build_H_record(new_record) 
    when "I" 
    factory_build_I_record(new_record) 
    when "D" 
    factory_build_e_record(new_record) 
    end 

對於重構,我試圖按照在面向對象編程中使用case語句Sandi Metz' blog post和消除case語句。我的傾向是我需要創建一些代表三種記錄類型的類,然後定義一些方法,如process_record。我不知道我應該如何去創建類。任何幫助,將不勝感激。

+0

我不喜歡修補核心類的猴子,除非有真正的好理由。 – pguardiario

回答

0

案例語句對於小型和相當靜態的條件案例(如您擁有的案例)並不壞。

如果(理論上)您預期未來有更多的記錄類型(除H,I和D之外),那麼case語句的問題是它可能會導致您開始違反Open-Closed Principle

在這種情況下,您可以創建一組RecordType類就是沿着這些路線的東西:

class HeaderRecordType 
    def is_mine(record) 
    ... 
    end 
    def build(record) 
    ... 
    end 
end 

class DataRecordType 
    ... 
end 

class SomeNewRecordType 
    ... 
end 

然後,不是的話,你只需遍歷所有RecordType的列表(或使用Chain of Responsibility)並詢問每一個is_mine(record)。只要其中一個人說好,那麼你就停下來看看並打電話給build

1

您鏈接的博客帖子具體是關於使用case聲明來告訴什麼類型的對象。這往往是設計不好的一個症狀,這就是她所做的一點。

您使用case語句的方式更加可以接受。實際上,無論您如何重組此結構,您都將針對該列進行某種測試(caseif或其他),以確定該行的正確行爲。

如果您的代碼稍後必須嘗試通過類別區分這些對象(使用case語句或if),那麼您違反了博客文章的精神。

該解決方案是創建一個具有相同的接口(具有相同方法的對象,以同樣的方式使用。這些方法的行爲是每班做正確的事情該對象內部不同。

希望這有助於爲您理清概念:)

+0

感謝您的迴應。那麼你是說我的代碼沒問題,或者我需要創建具有相同接口的對象 - 我相信這被稱爲鴨子打字,是的? – user365853

+0

它被稱爲多態。 – sawa

+0

如果您願意,您可以保留該代碼。由'factory_build_H_record','factory_build_I_record'返回的對象應該有相似的接口,所以你可以稍後在代碼中以統一的方式使用它們。 – ctcherry