通过工厂 + 策略 + 模板设计模式对f else业务逻辑进行优化
需要优化的业务代码:
@SpringBootTest
class FansApplicationTests2 {
@Test
String noDesign2() {
String name = "张三";
if (name.equals("张三")) {
// 业务逻辑B
return "张三完成任务BBB";
} else if (name.equals("李四")) {
// 业务逻辑B
return "李四完成任务BBB";
} else if (name.equals("王五")) {
// 业务逻辑B
return "王五完成任务BBB";
} else if (name.equals("赵六")) {
// 业务逻辑A
System.out.println("赵六完成任务AAA");
} else if (name.equals("田七")) {
// 业务逻辑A
System.out.println("田七完成任务AAA");
} else if (name.equals("亢八")) {
// 业务逻辑A
System.out.println("亢八完成任务AAA");
}
return "end";
}
//
@Test
void design2() {
String name = "亢八";
AbstractHandler strategy = Factory2.getInvokeStrategy(name);
System.out.println(strategy.run(name));
}
}
这个代码可能会存在哪些问题呢?
- 如果分支变多,这里的代码就会变得臃肿,难以维护,可读性低。
- 如果你需要接入一种新的解析类型,那只能在原有代码上修改。
说得专业一点的话,就是以上代码,违背了面向对象编程的开闭原则以及单一原则。
- 开闭原则(对于扩展是开放的,但是对于修改是封闭的):增加或者删除某个逻辑,都需要修改到原来代码
- 单一原则(规定一个类应该只有一个发生变化的原因):修改任何类型的分支逻辑代码,都需要改动当前类的代码。
如果你的代码就是酱紫:有多个if...else
等条件分支,并且每个条件分支,可以封装起来替换的,我们就可以使用策略模式来优化。
模版方法实现:
/**
* 模板方法设计模式
*/
public abstract class AbstractHandler implements InitializingBean {
public void AAA(String name) {
throw new UnsupportedOperationException();
}
public String BBB(String name) {
throw new UnsupportedOperationException();
}
public String run(String name) { throw new UnsupportedOperationException(); }
}
使用抽象类而不使用接口的目的是,策略子类不用将每个方法进行实现,这样写更加灵活。
工厂模式实现:
将策略类放进策略工厂方便调用
/**
* 工厂设计模式
*/
public class Factory {
// String:代表if else 中的条件 AbstractHandler是策略类
private static Map<String, AbstractHandler> strategyMap = Maps.newHashMap();
/**
* 通过条件返回对用的策略类
* @param str
* @return
*/
public static AbstractHandler getInvokeStrategy(String str) {
return strategyMap.get(str);
}
/**
* 注册方法
* @param str 条件
* @param handler 策略类
*/
public static void register(String str, AbstractHandler handler) {
if (StringUtils.isEmpty(str) || null == handler) {
return;
}
strategyMap.put(str, handler);
}
}
策略模式实现:
根据不同的写不同的策略(@Component一定要加上交给Spring管理 不然是不生效的)
// 李四策略实现
@Component
public class LiSiHandler extends AbstractHandler {
@Override
public String BBB(String name) {
// 业务逻辑B
return "李四完成任务B";
}
@Override
public String run(String name) {
// 业务逻辑B
return BBB(name);
}
//将LiSiHandler策略类注册到工厂方法中
@Override
public void afterPropertiesSet() throws Exception {
Factory.register("李四", this);
}
//亢八策略实现
@Component
public class KangBaHandler extends AbstractHandler {
@Override
public void AAA(String name) {
// 业务逻辑A
System.out.println("亢八完成任务");
}
@Override
public String run(String name) {
// 业务逻辑B
AAA(name);
return null;
}
//将KangBaHandler策略类注册到工厂方法中 this代表当前类
@Override
public void afterPropertiesSet() throws Exception {
Factory2.register("亢八", this);
}
afterPropertiesSet方法: 是InitializingBean接口中的方法,在spring的bean的生命周期中,实例化->生成对象->属性填充后会进行afterPropertiesSet方法,这个方法可以用在一些特殊情况中,也就是某个对象的某个属性需要经过外界得到,比如说查询数据库等方式,这时候可以用到spring的该特性,只需要实现InitializingBean即可
方法调用:
// 工厂 + 策略 + 模板设计模式
@Test
void design() {
// String name = "亢八";
String name = "李四";
AbstractHandler strategy = Factory2.getInvokeStrategy(name);
System.out.println(strategy.run(name));
}
这样就把多行的if else通过通过工厂 + 策略 + 模板设计模式进行了优化,又臭又长的if esle优化成了三行,将自己的代码level又提升了一个档次