论坛首页 Java企业应用论坛

策略模式在项目中的具体应用

浏览 5716 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-08-02  
往往大师级别的设计是简单的,易懂的,可扩展的,从不做作,整齐的代码让阅读的人感到很舒服。最近在看一个开源项目的源码,其中有好多的设计思想可以借鉴,相信这些优雅的代码也是在大量实践基础上,通过不断的重构而形成的。有一小段代码自认为写的不错,以下是源码:
EPAdministratorImpl类中:
java 代码
 
  1. private static ParseRuleSelector patternParseRule;  
  2. private static ParseRuleSelector eqlParseRule;  
  3.   static  
  4.   {  
  5.       patternParseRule = new ParseRuleSelector()  
  6.       {  
  7.           public void invokeParseRule(EQLStatementParser parser) throws TokenStreamException, RecognitionException  
  8.           {  
  9.               parser.startPatternExpressionRule();  
  10.           }  
  11.       };  
  12.   
  13.       eqlParseRule = new ParseRuleSelector()  
  14.       {  
  15.           public void invokeParseRule(EQLStatementParser parser) throws TokenStreamException, RecognitionException  
  16.           {  
  17.               parser.startEQLExpressionRule();  
  18.           }  
  19.       };  
  20.   
  21.   }  


这里用匿名内部类对接口ParseRuleSelector进行实现,并加到static块中,在LoadClass的时候,初始化成员变量patternParseRule和eqlParseRule,是策略模式的实现方,而对于这两个成员变量的使用仅仅在该类里的一个方法中:
java 代码
  1. AST ast = ParseHelper.parse(expression, patternParseRule);  

在其他地方这两个实现是不可用的,达到了很好的封装,因为ParseRuleSelector的目的就是选择EQLStatementParser的执行策略,不带有具体的业务数据,因此做成静态变量,使得对于一个Class仅有一个实例,节省内存。

在ParseHelper中的方法
java 代码
 
  1. public static AST parse(String expression, ParseRuleSelector parseRuleSelector) throws EPException {  
  2.         EQLStatementLexer lexer = new EQLStatementLexer(new StringReader(expression));  
  3.         EQLStatementParser parser = new EQLStatementParser(lexer);  
  4.         parseRuleSelector.invokeParseRule(parser);  
  5.         }  

调用接口,是面向接口编程,是策略模式的执行方,让具体的实现在EPAdministratorImpl中的匿名内部类完成。这样对于加入EQLStatementParser中的新方法,都可以在EPAdministratorImpl中对接口进行匿名实现,从而达到扩展的目的,并不需要改动ParseHelper。
   发表时间:2007-08-05  
弱弱的问下,实例中就两个策略类,如果策略较多咋办
0 请登录后投票
   发表时间:2007-08-05  
david_mou 写道
弱弱的问下,实例中就两个策略类,如果策略较多咋办


这里的代码只是一部分,原来的代码多于2个策略,如果你说的这里的策略过于复杂,可以单独的对策略部分进行OO分析和设计。
0 请登录后投票
   发表时间:2007-11-06  
策略模式就是这么个缺点,如果分支多了,子类也就多了,对于客户端也要了解所有的策略。
0 请登录后投票
   发表时间:2007-11-06  
不知楼主 创建 EQLStatementParser是否也使用策略模式

EQLStatementLexer lexer = new EQLStatementLexer(new StringReader(expression));   
EQLStatementParser parser = new EQLStatementParser(lexer); 


这段代码如果想告诉我们ParseRuleSelector使用了策略模式,写这段代码我认为清晰点:

ParseRuleSelector rule = getParseRuleSelector();   //获得EQL或Partten 策略
ASL asl = ParseHelper.parse(expression,rule);
0 请登录后投票
   发表时间:2007-11-06  
[quote="yongyuan.jiang"]不知楼主 创建 EQLStatementParser是否也使用策略模式 [code] EQLStatementLexer lexer = new EQLStatementLexer(new StringReader(expression)); EQLStatementParser parser = new EQLStatementParser(lexer); [/code] 这段代码如果想告诉我们ParseRuleSelector使用了策略模式,写这段代码我认为清晰点: [code] ParseRuleSelector rule = getParseRuleSelector(); //获得EQL或Partten 策略 ASL asl = ParseHelper.parse(expression,rule); [/code][/quote]

EQLStatementParser没有用策略模式,其实java中的策略模式可以等同为C或者C++中的函数指针,传递给函数public static AST parse(String expression, ParseRuleSelector parseRuleSelector) throws EPException的策略ParseRuleSelector,其实是用的该类里边的invokeParseRule(EQLStatementParser parser)方法;
具体的策略类通常是用匿名类来实现的,在本例中,静态成员变量patternParseRule和eqlParseRule的初始化都是用匿名内部类,来选择是调用策略startPatternExpressionRule,还是调用策略startEQLExpressionRule。

[code] ParseRuleSelector rule = getParseRuleSelector(); //获得EQL或Partten 策略 [/code]
你所说的这段代码也是获得的ParseRuleSelector,我感觉调用方是具体策略的选择者,而不是利用执行方获得默认的策略ParseRuleSelector。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics