0

I'm trying to refactor some code that reads a csv file. The first character in every line of the file indicates the type of record: H = Header, I = Information, and D = Data. Each record type has a fixed and different number of fields. My program uses FasterCSV to read a line from the file and then uses a case statement to determine how to process the line.

     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

For refactoring, I'm trying to follow Sandi Metz' blog post on the use of case statements in OO programming and eliminate case statements. My inclination is that I need to create some classes that represent the three record types and then define some methods like process_record. I'm not sure how I should go about to create the classes. Any help would be appreciated.

4

2 回答 2

1

您链接的博客文章专门关于使用case语句来判断某物是什么类型的对象。这通常是糟糕设计的症状,这就是她要表达的观点。

您使用case语句的方式更容易接受。事实上,无论您如何重组它,您都将对该列进行某种测试(case、 或if或其他方式)以确定该行的正确行为。

如果您的代码稍后必须尝试通过它们的类来区分这些对象(使用 case 语句或 if),那么您就违反了博客文章的精神。

解决方案是创建具有相同接口的对象(具有相同的方法,以相同的方式使用。这些方法的行为在每个类内部是不同的,以便为该对象做正确的事情。

希望这有助于为您澄清这个概念:)

于 2013-08-07T02:53:13.073 回答
0

案例语句对于像您所拥有的那样的小型且相当静态的条件案例来说还不错。

如果(理论上)您预计将来会有更多的记录类型(除了 H、I 和 D),那么 case 语句的问题在于它可能会导致您开始违反开闭原则

在这种情况下,您可能会创建一组RecordType类似于以下内容的类:

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

class DataRecordType
   ...
end

class SomeNewRecordType
   ...
end

然后,而不是这种情况,您只需遍历所有RecordType's 的列表(或使用责任链)并询问每个's is_mine(record)。一旦他们中的一个人说是,然后你停止寻找并打电话build

于 2013-08-07T05:29:13.253 回答