package com.cheng.zenofdesignpatterns.perfectworld.factory_strategy; import android.view.View; import com.cheng.zenofdesignpatterns.ZoDPChapterBaseActivity; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class ZoDPFactoryStrategyActivity extends ZoDPChapterBaseActivity { @Override protected void initData() { mTitleTV.setText("工厂方法模式 + 策略模式"); String content = "小结:\n" + "迷你版的交易系统案例中使用了如下几个模式:\n" + "- 策略模式\n" + "负责对扣款策略进行封装,保证两个策略可以自由切换,而且日后增加扣款策略也非常简单" + "容易。\n" + "- 工厂方法模式\n" + "修正策略模式必须对外暴露具体策略的问题,由工厂方法模式直接产生一个具体策略对象," + "而其他模块则不需要依赖具体的策略。\n" + "- 门面模式\n" + "负责对复杂的扣款系统进行封装,封装的结果就是避免高层模块深入子系统内部,同时提供" + "系统的高内聚、低耦合的特性。\n" + "主要使用了这三个模式,它们的好处是灵活、稳定,可以设想一下可能有哪些业务变化。\n" + "- 扣款策略变更\n" + "增加一个新的扣款策略,三步就可以完成:实现IDeduction接口,增加StrategyMan配置项," + "扩展扣款策略的利用(也就是门面模式的getDeductionType方法,在实际项目中这里只需要" + "增加数据库的配置项)。减少一个策略很简单,修改扣款策略的利用即可。变更一个扣款策略" + "也很简单,扩展一个实现类就可以了。\n" + "- 变更扣款策略的利用规则\n" + "系统不想大修改,还记得状态模式吗?这个就是为策略的利用服务的,变更它就能满足要求。" + "想把IC卡也纳入策略利用的规则也不复杂。这个还真发生了,系统投产后,业务提出考虑退休" + "人员的情况,退休人员的IC卡与普通在职员工一样,但是它的扣款不仅仅是根据交易编码,还" + "要根据IC卡对象,系统的变更做法是增加一个扣款策略,同时扩展扣款利用策略,也就是数据" + "库的配置项,在getDeductionType中新扩展了一个功能:根据IC卡号,确定是否是退休人员," + "是退休人员,则使用新的扣款策略,这是一个非常简单的扩展。"; mContentTV.setText(content); } @Override public void onClick(View v) { // 使用工厂方法模式和策略模式模拟交易 // 初始化一张IC卡 Card card = initIC(); // 显示一下卡内信息 System.out.println("========初始卡信息:========="); showCard(card); // 是否停止运行标志 boolean flag = true; while (flag) { Trade trade = createTrade(); DeductionFacade.deduct(card, trade); // 交易成功,打印出成功处理消息 System.out.println("\n======交易凭证========"); System.out.println(trade.getTradeNo() + " 交易成功!"); System.out.println("本次发生的交易金额为:" + trade.getAmount() / 100.0 + " 元"); // 展示一下卡内信息 showCard(card); System.out.print("\n是否需要退出?(Y/N)"); if (getInput().equalsIgnoreCase("y")) { flag = false; // 退出; } } } // 初始化一个IC卡 private Card initIC() { Card card = new Card(); card.setCardNo("1100010001000"); card.setFreeMoney(100000); // 一千元 card.setSteadyMoney(80000); // 八百元 return card; } // 产生一条交易 private Trade createTrade() { Trade trade = new Trade(); System.out.print("请输入交易编号:"); trade.setTradeNo(getInput()); System.out.print("请输入交易金额:"); trade.setAmount(Integer.parseInt(getInput())); // 返回交易 return trade; } // 打印出当前卡内交易余额 public void showCard(Card card) { System.out.println("IC卡编号:" + card.getCardNo()); System.out.println("固定类型余额:" + card.getSteadyMoney() / 100.0 + " 元"); System.out.println("自由类型余额:" + card.getFreeMoney() / 100.0 + " 元"); } // 获得键盘输入 public String getInput() { String str = ""; try { str = (new BufferedReader(new InputStreamReader(System.in))).readLine(); } catch (IOException e) { // 异常处理 } return str; } }