首页 > 编程知识 正文

java 策略模式实例,java中简单if语句案例

时间:2023-05-06 05:28:20 阅读:274082 作者:4234

java策略模式去掉冗余if-else支付案例实战 前言

上一篇文章介绍了 java中冗余if-else代码块的优化(策略模式法,反射法)
,里面详细介绍了策略模式+工厂模式来解决代码中大量的if-else结构。

这一篇就举个实战例来说明,怎么使用策略模式。

1.支付案例需求

假设你在做的某个项目,需求就是页面选择不同的付款渠道,计算不同的折扣,进行扣款。

看到这个图片,有小伙伴在遇到诸如此类的需求的时候,想到的会是,很简单,if else 判段下就可以了嘛,if else 确实可以解决我们的问题,但是弊端也很明显:

代码冗长维护不便

谁叫我们学习过了策略模式+工厂模式来解决代码中大量的if-else结构呢?

2.策略设计模式干掉if-else(通用写法)

策略模式+工厂模式解决代码中大量的if-else结构的(通用写法),以后遇到多条件的业务需求,就直接可以复用了。

文件目录:

1.定义充值支付的枚举类

RechargeTypeEnum.java 源码如下:

package PayDemo;/** * @Description: 1.定义枚举类型 * @Author: Zoutao * @Date: 2020/4/10 */public enum RechargeTypeEnum { /** * 枚举类型,根据业务需求增删 */ ABC_BANK(1,"农业银行"), ICBC_BANK(2,"工商银行"), /*根据自己到底业务需求增加个数*/ CCB_BANK(3,"建设银行"), CMB_BANK(4,"招商银行"),; /** * 状态值 */ private int code; /** * 类型描述 */ private String description; RechargeTypeEnum(int code, String description) { this.code = code; this.description = description; } public int getCode() { return code; } public String getDescription() { return description; } // 根据code获取对应的枚举类型 public static RechargeTypeEnum getPayTypeEnum(int code) { for (RechargeTypeEnum calcTypeEnum : RechargeTypeEnum.values()) { if (calcTypeEnum.getCode() == code) { return calcTypeEnum; } } System.out.println("对应支付计算策略不存在,[type={"+code+"}]"); return null; }} 2.定义支付的计算策略接口类

PayStrategy.java:

package PayDemo;/** * @Description: 2.定义支付的策略接口类 * @Author: Zoutao * @Date: 2020/4/10 */public interface PayStrategy { /** * 策略行为方法:定义根据金额进行结算的方法 * @param charge * @param type * @return */ public Double calRecharge(Double charge ,RechargeTypeEnum type);} 3.定义多个结算渠道具体的结算实现类

创建实现类的数量视自己的业务需求而定。

(针对每一类情况来分别实现上面接口,不是继承,是实现!!!
所以要在实现的方法中写好具体的计算规则代码。)

ABCPayStrategy.java
ICBCPayStrategy.java
CCBPayStrategy.java

比如我们写一个农业银行的,一个工商银行的。

ABCPayStrategy.java代码如下:

package PayDemo;/** * @Description: 具体有多少业务实现类,视自身业务而定 * @Author: Zoutao * @Date: 2020/4/10 */public class ABCPayStrategy implements PayStrategy { /** * 农业银行的结算实现类 * 优惠98折 * @param charge 金额 * @param type 支付类型 * @return */ @Override public Double calRecharge(Double charge, RechargeTypeEnum type) { return charge*0.98; }}

ICBCPayStrategy.java代码如下:

package PayDemo;/** * @Description: * @Author: Zoutao * @Date: 2020/4/10 */public class ICBCPayStrategy implements PayStrategy{ /** * 这边就是具体业务代码的实现方法 * 工商银行的结算实现类 * 收取5元手续费 * @return */ @Override public Double calRecharge(Double charge, RechargeTypeEnum type) { return charge+5; }}


实现类的数量视自己业务而定。

4.策略上下文类PayContext.java

作用就是根据类型路由到具体的实现类。
其中,创建接口的对象。
调用工厂类的getInstance和creator方法来路由到具体实现方法中。

package PayDemo;/** * @Description: 4.策略上下文,作用就是根据类型路由到具体的实现类 * @Author: Zoutao * @Date: 2020/4/10 */public class PayContext { // 创建接口的对象 private PayStrategy strategy; public Double calRecharge(Double charge, Integer type) { try{ strategy= StrategyFactory.getInstance().creator(type); // 调用工厂类的getInstance和creator方法 }catch (Exception e){ //log System.out.println("程序出错了!"); } return strategy.calRecharge(charge,RechargeTypeEnum.getPayTypeEnum(type)); } public PayStrategy getStrategy() { return strategy; } public void setStrategy(PayStrategy strategy) { this.strategy = strategy; }} 5.建立工程模式类StrategyFactory.java,

工厂模式来批量创建我们需要的类型的对象。new ABCPayStrategy(),new ICBCPayStrategy()。。。

package PayDemo;import java.util.HashMap;import java.util.Map;/** * @Description: 工厂模式-根据类型,把具体的实现类对象创建出来 * @Author: Zoutao * @Date: 2020/4/10 */public class StrategyFactory { //生成工厂对象 private static StrategyFactory factory = new StrategyFactory(); private StrategyFactory(){ } private static Map<Integer ,PayStrategy> strategyMap = new HashMap<>(); static{ //通过put或注解的方式把对象加载到map中 strategyMap.put(RechargeTypeEnum.ABC_BANK.getCode(), new ABCPayStrategy()); strategyMap.put(RechargeTypeEnum.ICBC_BANK.getCode(), new ICBCPayStrategy()); strategyMap.put(RechargeTypeEnum.CCB_BANK.getCode(), new CCBPayStrategy()); /* 自行增加业务需求 strategyMap.put(RechargeTypeEnum.CMB_BANK.getCode(), new CardStrategy());... */ } //工厂模式来创建我们需要的对象 public PayStrategy creator(Integer type){ return strategyMap.get(type); } //返回工厂对象 public static StrategyFactory getInstance(){ return factory; }} 6.接口的测试类PayTest.java,

必须创建上下文对象,调用接口方法calRecharge计算策略,得到对应的需求结果。

package PayDemo;/** * @Description: 上下文对象来调用对应的支付方式测试 * @Author: Zoutao * @Date: 2020/4/10 */public class PayTest { public static void main(String[] args) { // 创建上下文对象来调用对应的支付方式 PayContext context = new PayContext(); // 农业充值100 需要付多少 Double money = context.calRecharge(100D, RechargeTypeEnum.ABC_BANK.getCode()); System.out.println(money); // 工商充值100 需要付多少 Double money2 = context.calRecharge(100D, RechargeTypeEnum.ICBC_BANK.getCode()); System.out.println(money2); // 新增-建设银行充值方式 Double money3 = context.calRecharge(100D, RechargeTypeEnum.CCB_BANK.getCode()); System.out.println(money3); }}

以上就完成了一个策略模式+工厂模式的通用代码结构,在文章解决掉了所有的if-else结构,优化了代码,有利于后期的维护。

7.如果要新增一个新功能业务?

–以新建一个建设银行支付渠道为例。
(只需要新增代码而不需要修改原代码。这样设计程序的好处就体现出来了。)

a.首先在枚举类RechargeTypeEnum中新增类型和描述。

CCB_BANK(3,“建设银行”),

b.在增一个对应接口实现类CCBPayStrategy。
定义具体的接口方法内容。

package PayDemo;public class CCBPayStrategy implements PayStrategy { /** * 建设银行实现类 * 优惠96折 * @param charge * @param type * @return */ @Override public Double calRecharge(Double charge, RechargeTypeEnum type) { return charge * 0.96; }}

c.然后在工厂类StrategyFactory当中添加,生成对应的类对象和枚举类型。

strategyMap.put(RechargeTypeEnum.CCB_BANK.getCode(), new CCBPayStrategy());

d.最终在PayTest调用即可。

// 新增-建设银行充值方式 Double money3 = context.calRecharge(100D, RechargeTypeEnum.CCB_BANK.getCode()); System.out.println(money3);

结果:

至此我们业务功能就完成了,可能大家会觉得,设计模式的引入反而造成了类太多,还不如直接if else写在一个文件里的直观。

但是,对于后期的程序开发中,如果要新增一个付款渠道,使用策略模式的方式将变得很简单,只要定义一个具体的实现类,加上对应的工厂对象调用就解决了,根本不需要去阅读之前别人写的其他支付渠道的代码,松耦合的目的就在于此。

参考地址:
注解版:https://zhuanlan.zhihu.com/p/33383648
https://www.iteye.com/blog/alaric-1920714
https://blog.csdn.net/u014395955/article/details/103804479
https://www.toutiao.com/i6813584351410782723/

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。