在实际项目中使用工厂模式和策略模式解决实际生产中的过多if elseif 等分支语句

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

公司项目中有这样一个导出表格的需求,需要根据不同的设备型号,导出不同的表格,开始的时候为了快速的开发出来(主要是对需求的理解不够深入而且时间有限)在controller中使用了大量的if-else if -else if…-else,当再次增加新型号设备时,修改这段代码及其头疼,特别是时间长了,忘记了一些以前的逻辑,每次都得去捋一遍以前的逻辑是啥。近期在看设计模式相关的内容,发现可以使用简单工厂+策略模式解决这个问题。以此文来做记录。


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是策略模式和简单工厂

  1. 策略模式
    • 定义:该模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响使用算法的客户(此处的客户是指使用该策略的java类)
    • 抽象策略类(Strategy):定义一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
    • 具体策略(Concrete Strategy):实现了抽象策略定义的接口的类,提供了具体的算法实现。
    • 环境上下文类(Strategy Context):持有策略类的类,最终给客户端调用的类
  2. 工厂模式:简而言之,工厂模式就是用来产生对象的类

二、代码实现

代码实现没有具体的业务,只用了打印来代替

  1. 创建策略接口类
    代码如下(示例):
package com.example.stratage.strategy;

/**
 * @className: Stratage
 * @description: TODO 类描述
 * @author: xufh
 * @date: 2022/3/29
 */
public interface Stratage {
    void eportExcel();
}

  1. 为不同型号的设备实现策略接口
package com.example.stratage.strategy.impl;

import com.example.stratage.strategy.Stratage;
import org.springframework.stereotype.Component;

/**
 * @className: Model2028Stratage
 * @description: 2028型设备策略类实现
 * @author: xufh
 * @date: 2022/3/29
 */
@Component
public class Model2028Stratage implements Stratage {
    @Override
    public void eportExcel() {
        System.out.println("2028型仪器导出数据~~~~~~~~~~~~~~");
    }
}

package com.example.stratage.strategy.impl;

import com.example.stratage.strategy.Stratage;
import org.springframework.stereotype.Component;

/**
 * @className: Model2029Stratage
 * @description: TODO 类描述
 * @author: xufh
 * @date: 2022/3/29
 */
@Component
public class Model2029Stratage implements Stratage {
    @Override
    public void eportExcel() {
        System.out.println("2029型仪器导出数据~~~~~~~~~~~~~~");
    }
}

package com.example.stratage.strategy.impl;

import com.example.stratage.strategy.Stratage;
import org.springframework.stereotype.Component;

/**
 * @className: Model3012kStratage
 * @description: TODO 类描述
 * @author: xufh
 * @date: 2022/3/29
 */
@Component
public class Model3012kStratage implements Stratage {
    @Override
    public void eportExcel() {
        System.out.println("3012k型仪器导出数据~~~~~~~~~~~~~~~~~~~");
    }
}

  1. 创建策略上下文切换类
package com.example.stratage.context;

import com.example.stratage.strategy.Stratage;
import org.springframework.stereotype.Component;

/**
 * @className: StrategyContext
 * @description: TODO 类描述
 * @author: xufh
 * @date: 2022/3/29
 */
@Component
public class StrategyContext {
    private Stratage stratage;

    public StrategyContext() {
    }

    public void exportExcel() {
        if (stratage != null) {
            stratage.eportExcel();
        }
    }

    public Stratage getStratage() {
        return stratage;
    }

    public void setStratage(Stratage stratage) {
        this.stratage = stratage;
    }
}

  1. 创建工厂类
package com.example.stratage.factory;

import com.example.stratage.strategy.Stratage;
import com.example.stratage.strategy.impl.Model2028Stratage;
import com.example.stratage.strategy.impl.Model2029Stratage;
import com.example.stratage.strategy.impl.Model3012kStratage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

/**
 * @className: StrategyFactory
 * @description: TODO 类描述
 * @author: xufh
 * @date: 2022/3/29
 */
@Component
public class StrategyFactory {
    private static final Map<String, Stratage> strategies = new HashMap<>();

    public StrategyFactory() {
    }

    private Model3012kStratage model3012kStratage;
    private Model2028Stratage model2028Stratage;
    private Model2029Stratage model2029Stratage;

    @Autowired
    public StrategyFactory(Model3012kStratage model3012kStratage, Model2028Stratage model2028Stratage, Model2029Stratage model2029Stratage) {
        this.model3012kStratage = model3012kStratage;
        this.model2028Stratage = model2028Stratage;
        this.model2029Stratage = model2029Stratage;
        strategies.put("2028", model2028Stratage);
        strategies.put("2029", model2029Stratage);
        strategies.put("3012k", model3012kStratage);
    }

    @PostConstruct
    public void initStrategies() {
        strategies.put("2028", new Model2028Stratage());
        strategies.put("2029", new Model2029Stratage());
        strategies.put("3012k", new Model3012kStratage());
    }

    public Stratage getStratage(String type) {
        if (StringUtils.isEmpty(type)) {
            throw new RuntimeException("空参数");
        } else {
            return strategies.get(type);
        }

    }
}

  1. 客户端程序代码
package com.example.stratage.controller;

import com.example.stratage.context.StrategyContext;
import com.example.stratage.factory.StrategyFactory;
import com.example.stratage.strategy.Stratage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @className: DemoController
 * @description: TODO 类描述
 * @author: xufh
 * @date: 2022/3/29
 */
@RestController
@RequestMapping("/excel")
public class DemoController {
    @Autowired
    private StrategyFactory strategyFactory;
    @Autowired
    private StrategyContext strategyContext;

    @GetMapping("/{instModel}")
    public void export(@PathVariable("instModel") String instModel) {
        Stratage stratage = strategyFactory.getStratage(instModel);
        if (stratage == null) {
            System.out.println("stratage为空");
        } else {
            strategyContext.setStratage(stratage);
            strategyContext.exportExcel();
        }
    }
}

总结

以上就是这次的内容,设计模式的实际落地,通过工厂加策略模式去掉了大量的if else if 。。。,实现了解耦。当再有新的型号的设备需要导出时,只要实现策略接口,并在工厂中添加进去就可以了,不需要修改原来代码。语言表达能力比较差,多交流。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值