寻找“选择性”设计模式以避免if-else

时间:2014-05-21 12:35:32

标签: design-patterns

我有以下CSV条目:

2014-05-19 02:33:36,590,MGW,5147014,3056260212,ONNET,IN,CALL,95
2014-05-19 02:33:37,139,MGW,8827533,923049586878,ONNET,IN,NONCALL,95

2014-05-19 02:33:36,989,MGW,5463607,bbb063414604620,OMO,IN,CALL,95
2014-05-19 02:33:37,789,MGW,2677011,92bbb033368524299,OMO,IN,NONCALL,95

2014-05-19 02:33:38,750,MGW,8754053,OUT,ATI-REQ
2014-05-19 02:33:36,788,MGW,7652136,IN,ATI-RES,assumedIdle,0

2014-05-19 11:07:29,743,MGW,73011143,03636895,REDIRECTED,IN,CALL,95,92300142

2014-05-19 02:37:18,405,MGW,6313475,IN,ALERTSC
2014-05-19 02:07:02,507,MGW,6870068,IN,Report-RES
2014-05-19 02:07:02,710,MGW,7835732,OUT,Report-REQ

我在数据库中插入这些记录的算法可以这样工作:

if col[4] == "REDIRECTED"
//insert the 3rd column in 5th field in db
else if col.length > 7 and col[7] == "CALL"
//insert it without any change
else if col[5] == "ALERTSC" || "Report-REQ" || "Report-RES"
//insert all these with a common replacement of fields
else ignore all the rest

问题 我希望有一个模式:

  1. 我将此条目传递给所有类,无论哪一个对记录进程都有顾虑,

  2. 如果没有匹配记录的类,则会忽略该记录

  3. 工厂模式

    如果行识别器位于同一列上,则工厂模式将是选择,传送器将通过该列识别产品。但这里的标识符位于不同的位置,那么分销商/输送机如何将该行发送到各自的处理程序/工厂?

    我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:0)

使用不同的类来执行具有不同算法的相同任务是策略模式,但是Gang of Four对策略模式的原始定义不涉及选择策略。这种情况一直在发生,我会这样处理:

写一个类 - 让我们称之为Creator - 对于每种类型的CSV行,使用方法create!检查该行是否与类的类型匹配,解析该行(也许超类将在这里有用),将条目保存在数据库中并返回它。如果Creator与该行不匹配,则create!只返回nil。

然后,在“传送带”中:

lines.each do |line|
  [RedirectedCreator, CallCreator, AlertCreator].each |creator|
    if creator.new.create! line
      break
    end
  end
end

如果将条目保存到数据库的过程不是特定于行的类型,则可以让策略类解析该行并返回已解析的表单,并让调用者在一个地方执行保存。

此模式的另一个变体是策略类有一个方法accepts?,它接受​​项目处理并返回true或false而不实际做任何事情,第二个方法实际上做了工作