我正在尝试重构一些读取csv文件的代码。文件每行中的第一个字符表示记录类型:H
=标题,I
=信息,D
=数据。每种记录类型都有固定且不同数量的字段。我的程序使用FasterCSV从文件中读取一行,然后使用case语句来确定如何处理该行。
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
对于重构,我试图遵循Sandi Metz' blog post在OO编程中使用case语句并消除case语句。我倾向于我需要创建一些代表三种记录类型的类,然后定义一些像process_record
这样的方法。我不确定如何创建课程。任何帮助将不胜感激。
答案 0 :(得分:1)
您链接的博客文章具体是关于使用case
语句来判断什么类型的对象是什么。这通常是设计糟糕的症状,而这正是她所要做的。
您使用case
语句的方式更为可接受。事实上,无论你如何重组这个,你都要对该列进行某种测试(case
或if
或其他方式),以确定行的正确行为
如果您的代码稍后必须尝试通过他们的类(使用case语句或if)来区分这些对象,那么您违反了博客文章的精神。
解决方案是创建具有相同接口的对象(具有相同的方法,以相同的方式使用。这些方法的行为在每个类的内部是不同的,以便为该对象做正确的事。
希望这有助于为您理清概念:)
答案 1 :(得分: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
。