(策略模式+工厂模式)干掉if-else,让代码更优美

什么是策略模式: 

    我们创建表示各种策略的对象(超类)和一个行为随着策略对象改变而改变的具体对象(运行时),这种类型的设计模式属于行为型模式。

什么是工厂模式:

    工厂模式是用来创建对象的一种最常用的设计模式。是用工厂方法代替new操作的一种模式。我们不暴露创建对象的具体逻辑,而是将逻辑封装在一个函数中,那么这个函数就可以被视为一个工厂。
 

业务场景:

    用户生成订单需要调用支付接口,传统做法是if-else判断用户支付方式,调用不同的支付方式,这种做法无疑会造成大量的判断代码冗余,如果增加业务逻辑或新增支付方式需要修改代码,不利于代码的扩展性。

 @Test
  public void test01(){
    Order order = new Order();
    order.setName("张三");
    order.setUid("00");
    order.setOrderType("手机订单");
    order.setPanymentType("zhifubao");

    //实现支付
    String resultPany = this.panymentByBuilder(order.getPanymentType());
    System.out.println("resultPany = " + resultPany);
  }

  public String  panymentByBuilder(String PanymentType){
    if(PanymentType.equals("zhifubao")){
      return "使用**支付宝**支付成功";
    }else if(PanymentType.equals("weixin")){
      return "使用**微信**支付成功";
    }else if(PanymentType.equals("yinhangka")){
      return "使用**银行卡**支付成功";
    }else{
      return "使用**现金**支付成功";
    }
  }

实际业务中,支付的代码逻辑是相当复杂的,存在调用各种API和使用各种工具,那么我们能不能将所有的支付方式都归集到一个类(超类),由不同的业务子类去实现编写不同的支付逻辑呢?最好还能把子类通过工厂Bean管理,我们需要什么子类就获取什么子类,策略模式+工厂模式就能完美解决这个问题

  • 策略模式超类(抽象类):PaymentHandel
*     1.定义所有的业务逻辑性方法,也就是所有的支付方式
*     2.实现InitializingBean接口,初始化的时候将子类具体实现保存到bean工厂

 

/**
 * 策略模式 业务逻辑的抽取
 * @author zhangjiangfeng
 * @version 14:43
 *
 * InitializingBean Stringboot bean初始化接口(自定义bean实例化)
 */
public abstract class PaymentHandel implements InitializingBean {

  //支付方式
  public void panymentType(){
     throw new UnsupportedOperationException();
  }

  //支付来源
  public void orderType(){
    throw new UnsupportedOperationException();
  }

}
  • 子类实现PaymentHandel,拥有所有业务逻辑方法,和初始化bean接口
*     1.子类根据自身业务,实现部分业务逻辑代码功能
*     2.子类通过初始化bean接口,在初始化加载时将实例保存到bean工厂
/**
 * @author zhangjiangfeng
 * @version 15:23
 *
 */
@Component
@Data
public class ZhiFuBao extends PaymentHandel{


  @Override
  public void panymentType() {
    System.out.println("使用**支付宝**支付成功");
  }

  public void orderType(){
    System.out.println("使用**手机**完成支付");
  }

  @Override
  public void afterPropertiesSet() throws Exception {
  FactoryBean.register("ZhiFuBao",this.getClass());
  }
}

@Component
@Data
public class WeiXin extends PaymentHandel{



  @Override
  public void panymentType() {
    System.out.println("使用**微信**支付成功");;
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    FactoryBean.register("WeiXin",this.getClass());
  }
}

 

  •  工厂模式,用工厂方法代替new操作的一种模式。我们不暴露创建对象的具体逻辑
    *    1.工厂模式提供regist方法,以K-V形式,保存bean实例
    *    2.工厂模式提供get方法,根据参数K获取bean实例
**
 * 工厂设计模式
 * @author zhangjiangfeng
 * @version 15:52
 *
 */
@Component
public class FactoryBean {

  private static Map<String, Class> HandelMap = new HashMap<>();


  public static Class getHandel(String name){
    return HandelMap.get(name);
  }

  public static void register(String name,Class tClass){
    if(StringUtils.isNotBlank(name) && tClass!=null){
      HandelMap.put(name,tClass);
    }
  }

}

现在我们通过策略模式+工厂模式调用支付接口,由此我们省略了大量的if-else代码块,同时如果需要新增支付方式或修改支付逻辑,我们只用对实现超类PaymentHandel的子类做相应的处理,这里也实现了java面向对象的开闭原则:只允许扩展不允许修改

@Test
  public void test02() throws IllegalAccessException, InstantiationException {
    //业务获取到用户订单数据
//    Order order = new Order();
//    order.setName("WeiXin");
//    order.setUid("111");
//    order.setOrderType("1");
//    order.setPanymentType("1");

    //由工厂bean返回对象实例,根据K获取的实例是zhifubao
    Class<PaymentHandel>   handel  = FactoryBean.getHandel("ZhiFuBao");
    PaymentHandel        paymentHandel = handel.newInstance();
    //调用实例方法
    paymentHandel.panymentType();
  }
2021-04-21 14:42:27.009  INFO 11612 --- [           main] c.z.studytest.StudyTestApplicationTests  : Starting StudyTestApplicationTests using Java 1.8.0_181 on CTX-MCS-DEV023 with PID 11612 (started by zhangjiangfeng in C:\IDEAWorkSpace1\study-test)
2021-04-21 14:42:27.015  INFO 11612 --- [           main] c.z.studytest.StudyTestApplicationTests  : No active profile set, falling back to default profiles: default
2021-04-21 14:42:28.587  INFO 11612 --- [           main] c.z.studytest.StudyTestApplicationTests  : Started StudyTestApplicationTests in 2.281 seconds (JVM running for 4.818)
使用**支付宝**支付成功

Process finished with exit code 0

总结:

合理的运用设计模式,可以让我们的代码可读性,可维护性更好,设计模式是一种编程思想,并不是一成不变的模板,要切合实际业务去尝试使用设计模式。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值