锁定老帖子 主题:模式新手,向高手请教。策略模式这样用对吗?
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-05-07
首先这是一个对帐功能,就是从数据库A得到表1的交易,去和数据库B中表2的交易去匹配,如果没什么问题就pass,一旦有不和谐的地方就作为异常交易显示出来。以下是活动图: 思路大致这样,先得到交易的状态(确认成功,确认失败,已撤销,未确认),根据不同状态去选择不同策略(我当时就这么想的,后来多少感觉有点问题,也许这个根本不是策略模式,唉,就请大家看看) [img]http://jorwen-fang.iteye.com/upload/picture/pic/3230/bdf25f35-a14f-4a21-8351-e5f6c9f8fe2d.jpg [/img] 1. action部分代码 List<RequestTrade> exceptionTradeList = new ArrayList(); try { CheckTradeService service = CheckTradeService.getInstance(); List<RequestTrade> trades = service.findAllTradeByDate(((CheckTradeForm )form).getWorkDate()); for( RequestTrade trade:trades ) { RequestTrade afterCheckTrade = trade.check(); if(afterCheckTrade.isException()) { exceptionTradeList.add( trade ); } } } catch( Exception e ) { e.printStackTrace(); } //........ 2.RequestTrade.java 就是表1的javabean而且还是策略类的Context,身兼2职 public class RequestTrade { private Strategy strategy; private String fundAccNo; private String tradeAccNo; private String requestNo; private String voucherNo; private String requestDate; private String requestTime; private String businFlag; private String fundCode; private Long balance; private String state; private String confirmFlag; private String moneyType; private String originNo; private String exceptionReason; public RequestTrade check() { return strategy.check( this ); } //如果exceptionReason最后没有,说明正常,否则就是异常,这里我偷懒了,就这样设计了 public boolean isException() { return getExceptionReason() != null && !getExceptionReason().equals(""); } public void setConfirmFlag( String confirmFlag ) { this.confirmFlag = confirmFlag; initStrategy(); } //其他set,get //此时根据不同confirmFlag选择不同策略 private void initStrategy() { if ( confirmFlag.equals( "0" ) ) { strategy = new StrategyConfirmFailure(); } else if ( confirmFlag.equals( "1" ) ) { strategy = new StrategyConfirmSuccess(); } else if ( confirmFlag.equals( "4" ) ) { strategy = new StrategyAlreadyRepeal(); } else if ( confirmFlag.equals( "9" ) ) { strategy = new StrategyUnconfirm(); } } } 3.策略类父类 public abstract class Strategy { protected RequestTrade trade;//表1的javabean protected Statement stmt;//表2的javabean,由于只有属性和set,get就省略显示此类 protected CheckTradeService service = CheckTradeService.getInstance(); //流程,由于4种策略都要有findTrade()和checkMoney(),之后才是各自不同的逻辑 public final RequestTrade check(RequestTrade trade) { this.trade = trade; try { findTrade(); if(stmt != null) { checkMoney(); otherOperate(); } } catch( NoSuchTradeException e ) { trade.setExceptionReason( "找不到该交易" ); } catch( MoneyIsNotMatchException e ) { trade.setExceptionReason( "金额不匹配" ); } catch( UnsuccessfulTradeException e ) { trade.setExceptionReason( "状态不匹配,为失败" ); } catch( SuccessfulTradeException e ) { trade.setExceptionReason( "状态不匹配,为成功" ); } return this.trade; } final void checkMoney() throws CheckTradeException { if(stmt.getTradeMoney() != trade.getBalance()) throw new MoneyIsNotMatchException(); } //这里是这个意思.有些状态从表2中找不到交易是允许的,有些找不到是异常交易 protected final void findStmt(boolean ifNotFindIsException) throws CheckTradeException { Statement tmp = service.findStmt( trade.getRequestNo() ); if(ifNotFindIsException) { if(tmp == null) throw new NoSuchTradeException(); else this.stmt = tmp; } else { if(tmp != null) this.stmt = tmp; } } abstract protected void findTrade() throws CheckTradeException; abstract protected void otherOperate() throws CheckTradeException; } 4.策略子类,其他3个也差不多,就省略了 public class StrategyConfirmSuccess extends Strategy { protected void findTrade() throws CheckTradeException { this.findStmt( true );//表示找不到对应交易作为异常交易 } protected void otherOperate() throws CheckTradeException { if(!stmt.isSuccessStmt()) { throw new UnsuccessfulTradeException(); } } } 大致就这样设计的,请大家给予强烈批判,因为我觉得肯定问题很多。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-05-08
我觉得没什么大问题,关键的地方就是几个策略的注入问题。initStrategy不是很理想,不如就setStrategy吧,直接把实现注入.
|
|
返回顶楼 | |
发表时间:2007-05-08
没有对不对,只有合适不合适
|
|
返回顶楼 | |
发表时间:2007-05-08
State模式更贴切一点
|
|
返回顶楼 | |
发表时间:2007-05-08
个人感觉这样一个策略+模板的设计还是不错的。
状态和策略从类图上看就是差不多的。 区别个人感觉State偏向于静态的状态,而策略是偏向于行为。 我也是新手。。。 |
|
返回顶楼 | |
发表时间:2007-05-08
ohlala 写道 State模式更贴切一点
这位说的不错,不过state和strategy本来就是一种模式,只是目的不同才称做两种模式。 |
|
返回顶楼 | |
发表时间:2007-05-08
感谢各位指点,今天还看到设计模式专区里的文章。说没必要刻意使用模式,代码些多了,有经验了,勤于思考者写出来的代码已经潜意识在使用模式,甚至自己也不知道是哪一招。
明白了,我把模式看得太神圣了 |
|
返回顶楼 | |
发表时间:2007-05-08
只要代码没味那就是好代码
如果代码有味再好的模式也不好 |
|
返回顶楼 | |
发表时间:2007-05-26
把所有的变化的抽象都取出来,这取一个,那取一个,仔细分析下,咦,这不就是xx模式+yy模式吗??
自己都不知道自己到底是用了什么了 |
|
返回顶楼 | |
发表时间:2007-05-26
# //此时根据不同confirmFlag选择不同策略
# private void initStrategy() # { # if ( confirmFlag.equals( "0" ) ) # { # strategy = new StrategyConfirmFailure(); # } # else if ( confirmFlag.equals( "1" ) ) # { # strategy = new StrategyConfirmSuccess(); # } # else if ( confirmFlag.equals( "4" ) ) # { # strategy = new StrategyAlreadyRepeal(); # } # else if ( confirmFlag.equals( "9" ) ) # { # strategy = new StrategyUnconfirm(); # } # } 这个方法的代码好像有点多余,直接用set动态注入策略的实现应该更好点。 |
|
返回顶楼 | |