项目中使用策略模式+工厂模式实现导入导出

因为,最近在做excle的导入导出,发现有一个模块地下有14个需要导入导出的类,思来想去用策略+简单工厂模式去除if else if ....,是该模块能更好的维护。带着这样的想法,便在度娘搜了下策略+工厂模式的实现,最后参考了这位老哥的https://www.cnblogs.com/huangqingshi/p/10344265.html文章,

先附上代码:

1.定义一个导入导出的接口:

public interface ExcelOperationStrategy {

    void importExcel(InputStream inputstream,ImportParams params);

    void exportExcel(String id);
}

2.创建一个策略工厂:

    @Autowired
    Map<String, ExcelOperationStrategy> strategys = new ConcurrentHashMap<>(14);

3.实现接口

@Component("test")
public class StrategyTest  implements ExcelOperationStrategy {
//省略了大部门代码
    @Override
    public void importExcel(InputStream inputstream, ImportParams params) {
        long start1 = System.currentTimeMillis();
         do samething

    }

    @Override
    public void exportExcel(String id) {
          Error error = errorMapper.selectByPrimaryKey(id);
            if (StringUtils.isNotEmpty(error.getContent00())) {
            List<TestEntity> list = new ArrayList<>();
            list = JSONObject.parseArray(error.getContent00(), TestEntity.class);
            FileWithExcelUtil.exportExcel(list, "测试表", "测试",             TestEntity.class, "测试表.xls", response);
        }
    }
}





@Component("test1")
public class StrategyTest1  implements ExcelOperationStrategy {
//省略了大部门代码
    @Override
    public void importExcel(InputStream inputstream, ImportParams params) {
        long start1 = System.currentTimeMillis();
         do samething

    }

    @Override
    public void exportExcel(String id) {
          Error error = errorMapper.selectByPrimaryKey(id);
            if (StringUtils.isNotEmpty(error.getContent00())) {
            List<Test1Entity> list = new ArrayList<>();
            list = JSONObject.parseArray(error.getContent00(), Test1Entity.class);
            FileWithExcelUtil.exportExcel(list, "测试表1", "测试1",             Test1Entity.class, "测试表1.xls", response);
        }
    }
}



@Component("test2")
public class StrategyTest2 implements ExcelOperationStrategy {
//省略了大部门代码
    @Override
    public void importExcel(InputStream inputstream, ImportParams params) {
        long start1 = System.currentTimeMillis();
         do samething

    }

    @Override
    public void exportExcel(String id) {
          Error error = errorMapper.selectByPrimaryKey(id);
            if (StringUtils.isNotEmpty(error.getContent00())) {
            List<Test1Entity> list = new ArrayList<>();
            list = JSONObject.parseArray(error.getContent00(), Test2Entity.class);
            FileWithExcelUtil.exportExcel(list, "测试表2", "测试1",             Test2Entity.class, "测试表2.xls", response);
        }
    }
}

..........

4.controller实现

    @RequestMapping(value = "uploadfile", method = RequestMethod.POST)
    @ResponseBody
    public AjaxResponse uploadfile(@RequestParam("file") MultipartFile file,String type)  {
        long startTime = System.currentTimeMillis();
        System.out.println("--------------------startTime------------------------------" + startTime);
        ImportParams params = new ImportParams();
        params.setHeadRows(1);
        params.setTitleRows(0);
        try {
            factoryForStrategy.getStrategy(type).importExcel(file.getInputStream(),params);
       
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            System.out.println("--------------------endtime------------------------------");
            long endtime = System.currentTimeMillis() - startTime;
            long minutes = (endtime / 1000) / 60;
            long seconds = (endtime / 1000) % 60;
            System.out.format("%d 毫秒 = %d 分钟 又 %d 秒.", endtime, minutes, seconds);
        }
        return AjaxResponse.success("导入数据成功!");
    }

其中我对

@Autowired
Map<String, ExcelOperationStrategy> strategys = new ConcurrentHashMap<>(14);为什么可以通过传一个bean名称,智能的调用相应的类方法呢?

首先通过查看@Autowired源码发现有这么一段话:

<p>In case of a {@link java.util.Collection} or {@link java.util.Map}
dependency type, the container will autowire all beans matching the
declared value type. In case of a Map, the keys must be declared as
type String and will be resolved to the corresponding bean names

大体上意思是对于CollectionMap的依赖类型,容器会自动装配所有与声明值类型匹配的bean。如果是Map,key必须是String类型,并将解析为相应的bean名称,value为相应的bean。

话不都说,上代码测试一下。

定义接口

public interface IAnimal {
    void eat();
}
@Component("cat")
public class Cat implements IAnimal {

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}



@Component("dog")
public class Dog implements IAnimal {

    @Override
    public void eat() {
        System.out.println("狗啃骨头");
    }
}

@Component("sheep")
public class Sheep implements IAnimal {

    @Override
    public void eat() {
        System.out.println("羊吃青草");
    }
}

注入

@Service
public class AnimalService {
    @Autowired
    List<IAnimal> animalList;
    @Autowired
    Map<String, IAnimal> animalMap;

    public void test() {
        System.out.println("--------------list:----------------");
        for (IAnimal iAnimal : animalList) {
            iAnimal.eat();
        }
        System.out.println("-------------------list end");
        System.out.println("---------------------map:--------------");
        for (Map.Entry<String, IAnimal> entry : animalMap.entrySet()) {
            System.out.println("Map:" + entry.getKey() + ", " + entry.getValue());
        }

    }

    public void testEat(String key) {
        IAnimal iAnimal = animalMap.get(key);
        if (null != iAnimal) {
            iAnimal.eat();
        }
    }
}

测试一波:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(Application.class);
        ApplicationContext context=springApplication.run(args);
        AnimalService bean = context.getBean(AnimalService.class);
        bean.test();
        System.out.println("策略模式测试");
        bean.testEat("dog");
    }

}

控制台输出:

 是不是感觉很神奇!,通过调用不同的实现类,即可达到策略模式的类似效果。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值