多个if-else代码:

@RunWith(SpringRunner.class)
@SpringBootTest
public class EducationalBackgroundTest {
private int year = 6; @Test
public void normalIfElse(){
if ( year == 6){
System.out.println("小学毕业");
}else if ( year == 9){
System.out.println("初中毕业");
}else if ( year == 12){
System.out.println("高中毕业");
}else {
System.out.println("未知学习时间");
}
}
}

上面只统计了3个学习时间,如果我们要写其他的学习时间就需要继续添加if-else,如果业务很复杂,那么这个代码看起来会很乱,不方便维护;

下面用策略模式和工厂模式优化该if-else;

1. 定义抽象策略角色(接口)

public interface EducationalBackground {
void process();
}

2. 编写具体策略角色(实现策略角色接口)

小学毕业策略角色:

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component; @Component
public class Primary implements EducationalBackground,InitializingBean { @Override
public void process() {
System.out.println("小学毕业");
}
@Override
public void afterPropertiesSet() throws Exception {
EducationBackgroundFactory.put(6,this);
} }

这里的InitializingBean接口(具体看Spring Bean的生命周期)只有一个方法afterPropertiesSet,实现了该接口的bean初始化会调用这个方法;

再写一个策略角色“初中毕业”:

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component; @Component
public class Junior implements EducationalBackground,InitializingBean { @Override
public void process() {
System.out.println("初中毕业");
}
@Override
public void afterPropertiesSet() throws Exception {
EducationBackgroundFactory.put(9,this);
} }

3. 环境角色,内部持有一个策略类的引用

简单工厂模式

import java.util.HashMap;
import java.util.Map;
import java.util.Optional; public class EducationBackgroundFactory {
private static Map<Integer,EducationalBackground> educationMap = new HashMap<>(); private EducationBackgroundFactory(){} private final static EducationalBackground EMPTY = new EmptyDesc(); /**
* 将对应年数的学历对象注册到Map中
* @param year
* @param educationalBackground
*/
public static void put(int year,EducationalBackground educationalBackground){
educationMap.put(year,educationalBackground);
} /**
*获得对应学历对象
* @param year
*/
public static EducationalBackground get(int year){
EducationalBackground educationalBackground = educationMap.get(year);
//没有对应year返回EMPTY
return Optional.ofNullable(educationalBackground).orElse(EMPTY);
} private static class EmptyDesc implements EducationalBackground{
@Override
public void process() {
System.out.println("未知的学习时间year");
}
} }

测试方法:

@RunWith(SpringRunner.class)
@SpringBootTest
public class EducationalBackgroundTest {
private int year = 6; /**
* 设计之后仅需两行代码
*/
@Test
public void design(){
EducationalBackground educationalBackground = EducationBackgroundFactory.get(year);
educationalBackground.process();
} }

有关于year的参数最好是配置在配置文件中,比如项目已上线,只需要修改配置文件中的内容即可修改对应的引用,而不需要修改代码(修改了代码需要发布)!

参考来源:

https://www.cnblogs.com/pfblog/p/7815238.html

用工厂模式和策略模式优化过多的if-else的更多相关文章

  1. ES6对抽象工厂模式与策略模式结合的实践

    这段代码是我在学习了java版的抽象工厂模式后,实现的ES6版抽象工厂,后期大幅修改,加入了策略模式,看起来很多逻辑看似繁琐,不必要写这么多,但是为了练习设计模式,所以才这样做.当所需的工厂种类增多后 ...

  2. 策略模式、策略模式与Spring的碰撞

    策略模式是GoF23种设计模式中比较简单的了,也是常用的设计模式之一,今天我们就来看看策略模式. 实际案例 我工作第三年的时候,重构旅游路线的机票查询模块,旅游路线分为四种情况: 如果A地-B地往返都 ...

  3. 大型Java进阶专题(七) 设计模式之委派模式与策略模式

    前言 ​ 今天开始我们专题的第七课了.本章节将介绍:你写的代码中是否觉得很臃肿,程序中有大量的if...else,想优化代码,精简程序逻辑,提升代码的可读性,这章节将介绍如何通过委派模式.策略模式让你 ...

  4. Provider Pattern提供者模式和策略模式

    http://www.codeproject.com/Articles/18222/Provider-Pattern Introduction Provider pattern is one of t ...

  5. Android设计模式之命令模式、策略模式、模板方法模式

    命令模式是其它很多行为型模式的基础模式.策略模式是命令模式的一个特例,而策略模式又和模板方法模式都是算法替换的实现,只不过替换的方式不同.下面来谈谈这三个模式. 命令模式 将一个请求封装为一个对象,从 ...

  6. 我学的是设计模式的视频教程——命令模式vs策略模式,唠嗑

    课程视频 命令模式vs策略模式 唠嗑 课程笔记 课程笔记 课程代码 课程代码 新课程火热报名中 课程介绍 版权声明:本文博主原创文章,博客,未经同意不得转载.

  7. 模式PK:命令模式VS策略模式

    1.概述 命令模式和策略模式的类图确实很相似,只是命令模式多了一个接收者(Receiver)角色.它们虽然同为行为类模式,但是两者的区别还是很明显的.策略模式的意图是封装算法,它认为“算法”已经是一个 ...

  8. C++模式学习------策略模式

    当遇到同一个对象有不同的行为,方法,为管理这些方法可使用策略模式. 策略模式就是对算法进行包装,是把使用算法的责任和算法本身分割开来.通常把一个系列的算法包装到一系列的策略类里面,这些类继承一个抽象的 ...

  9. 【设计模式】 模式PK:命令模式VS策略模式

    1.概述 命令模式和策略模式的类图确实很相似,只是命令模式多了一个接收者(Receiver)角色.它们虽然同为行为类模式,但是两者的区别还是很明显的.策略模式的意图是封装算法,它认为“算法”已经是一个 ...

随机推荐

  1. virt-install详解

    man virt-install VIRT-INSTALL() Virtual Machine Manager VIRT-INSTALL() NAME virt-install - provision ...

  2. The Kernel Boot Process.内核引导过程

    原文标题:The Kernel Boot Process 原文地址:http://duartes.org/gustavo/blog/ [注:本人水平有限,只好挑一些国外高手的精彩文章翻译一下.一来自己 ...

  3. Python开发之AJAX

    一.概述 对于WEB应用程序:用户浏览器发送请求,服务器接收并处理请求,然后返回结果,往往返回就是字符串(HTML),浏览器将字符串(HTML)渲染并显示浏览器上. 1.传统的Web应用:一个简单操作 ...

  4. 使用idea创建maven多模块项目

    前言 参看:http://blog.csdn.net/zht666/article/details/19040733 使用Maven管理项目时,往往需要创建多个模块,模块之间存在相互引用的关系.对于M ...

  5. .netLinq动态Where条件

    文章介绍全网最佳方式使用EF+Linq实现多条件组合查询:代码中没有使用到网上主流自定义Expression表达式而是采用linq原生态功能编写示例直观.易懂,且有效解决自定义Expression不支 ...

  6. WebForm多页面传值跳转

    一.URL传值 URL传值是利用跳转地址直接加变量定义内容 格式:跳转地址?任意变量=传的值--?=之间不能有空格 多条数据传值 在地址栏继续拼接&key=value void Button1 ...

  7. RabbitMq(2) 简单消息队列

    <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client </ar ...

  8. Django之视图层介绍

    1. 伪静态设置: 路由层: url('^index/$', views.index), url('^article/(?P<id>(\d+)).html/$', views.articl ...

  9. 【JEECG技术文档】JEECG高级查询构造器使用说明

    功能介绍   高级查询构造器支持主子表联合查询,查询出更精确的数据. 要使用高级查询构造器需要完成以下步骤: 1. 在高级查询管理配置主子表信息. 2. 配置完后在JSP页面DataGrid标签上添加 ...

  10. day15-函数进阶

    1.函数嵌套 多个函数嵌套在一起即为函数嵌套 在调用函数时,函数需在调用之前定义,如果函数在调用之后才定义,则不能被成功调用.当定义多个函数时,函数名称不能相同,否则后定义的函数会将之前的函数覆盖,即 ...