一:优化前的代码
public static void noDesign(String name){
if(name.equals("张三")){
//....业务逻辑
System.out.println("张三完成任务A");
}else if(name.equals("李四")){
//....业务逻辑
System.out.println("李四完成任务A");
}else if(name.equals("王五")){
//....业务逻辑
System.out.println("王五完成任务A");
}else if(name.equals("赵六")){
//....业务逻辑
System.out.println("赵六完成任务A");
}else if(name.equals("田七")){
//....业务逻辑
System.out.println("田七完成任务A");
}
}
可以看到在业务逻辑很复杂的情况下,这段代码既冗余又难以阅读,因此我们引入策略模式,创建一个接口,为每一个人新建一个handler实现这个接口
public interface Handler extends InitializingBean {
public void AAA(String name);
}
@Component
public class ZhangSanHandler implements Handler {
@Override
public void AAA(String name) {
//....业务逻辑
System.out.println("张三完成任务A");
}
/**
* 此方法实现了spring初始化bean类InitializingBean中的方法
* 当类加载到容器时会自动加载此方法,将类注册到Factory的Map中
* this代表当前类
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
Factory.register("张三",this);
}
}
@Component
public class LiSiHandler implements Handler {
@Override
public void AAA(String name) {
//....业务逻辑
System.out.println("李四完成任务A");
}
@Override
public void afterPropertiesSet() throws Exception {
Factory.register("李四",this);
}
}
第一次优化后的代码
public static void afterDesignOne(String name) {
if (name.equals("张三")) {
new ZhangSanHandler().AAA(name);
} else if (name.equals("李四")) {
new LiSiHandler().AAA(name);
} else if (name.equals("王五")) {
new WangWuHandler().AAA(name);
} else if(name.equals("赵六")){
//....
}
}
经过引入策略模式后,代码美观了不少,但是此时如果有田七或者其他人使用这个方法
则要继续修改这个方法,增加if else 耦合性较强,这显然是不符合开闭原则的 此时可以引入工厂设计模式
public class Factory {
private static Map<String, Handler> strategyMap = new HashMap<>();
public static Handler getHandler(String name){
return strategyMap.get(name);
}
/**
* 通过注册方法将key value注册到Map中
* 可以通过每个handler类里面的afterPropertiesSet()方法去注册
* 这样就可以每次新增一个handler而不用改动其他代码
* @param name
* @param handler
*/
public static void register(String name,Handler handler){
if(StringUtils.isEmpty(name)||null == handler){
return;
}
strategyMap.put(name, handler);
}
}
第二次优化后的代码
public static void afterDesignTwo(String name){
Handler handler = Factory.getHandler(name);
handler.AAA(name);
}
可以看到引入工厂模式后代码变得非常简洁,代码耦合性降低
但是仍然存在缺点:
此时假设张三实现的业务逻辑是BBB,不用实现AAA,并且返回的是字符串或者其他类型
此时就要在Handler类里面加上BBB方法 ,但是ZhangSanHandler里面AAA方法并不能删除
如果删除则报错,但是保留显然也是不合理的,此时可以引入模板设计方法
* @Description 模板方法设计模式
**/
public abstract class AbstractHandler implements InitializingBean {
public void AAA(String name){
throw new UnsupportedOperationException();
}
public String BBB(String name){
throw new UnsupportedOperationException();
}
}
public class Factory2 {
private static Map<String, AbstractHandler> strategyMap = new HashMap<>();
public static AbstractHandler getHandler(String name){
return strategyMap.get(name);
}
public static void register(String name,AbstractHandler handler){
if(StringUtils.isEmpty(name)||null == handler){
return;
}
strategyMap.put(name, handler);
}
}
public class ZhangSanHandler2 extends AbstractHandler{
@Override
public String BBB(String name){
return "张三完成任务B";
}
@Override
public void afterPropertiesSet() throws Exception {
Factory2.register("张三",this);
}
}
第三次优化后的代码
/**
* 工厂+策略+模板设计模式
* @param name
*/
public static void afterDesignThree(String name){
AbstractHandler handler = Factory2.getHandler(name);
handler.AAA(name);
String str = handler.BBB("张三");
}