背景
日常編碼中我們經常遇到 很多if else的代碼,比如
String name=""; if ("1A".equals(name)){ System.out.println("1111111AAAAAAAAA"); }else if("2B".equals(name)){ System.out.println("222222BBBBBB"); }else if("3C".equals(name)){ System.out.println("33333CCCCCCC"); }
Handler類的代碼:
@Component public class HandlerA1{public void A(String name) { System.out.println("1111111111AAAAAAAAAAAAA"); } }
第一步:使用策略模式優化if else里面的邏輯
把業務邏輯抽取到handler里面
String name=""; if ("1A".equals(name)){ new HandlerA1().A(name); }else if("2B".equals(name)){ new HandlerB1().A(name); }else if("3C".equals(name)){ new HandlerC1().A(name); }
第二步:使用工廠設計模式優化if
策略模式只是優化了if else里面的邏輯,並沒有把if干掉
下面我們使用工廠模式把if干掉
1.首先先寫一個工廠用來生成我們的策略handler(把所有的handler存放在工廠的strategyMap中)
public class Factory { private static Map<String,AbstractHandler> strategyMap = new ConcurrentHashMap<>(); public static void register(String name,AbstractHandler handler){ strategyMap.put(name,handler); } public static Handler getInvokeStrategy(String name){ return strategyMap.get(name); } }
2.我們的所有業務Handler都實現Handler接口
@Component public class HandlerA1 implements Handler{ @Override public void afterPropertiesSet() throws Exception { Factory.register("1A",this); } @Override public void A(String name) { System.out.println("1111111111AAAAAAAAAAAAA"); } @Override public void B(String name) { } @Override public void C(String name) { } }
3.而Handler接口有實現了InitializingBean接口
Spring啟動的時候會調用Handler的afterPropertiesSet方法 把Handler注冊到Factory工廠
public abstract interface Handler implements InitializingBean { /*** * 用抽象類做模板方法 * @param name */ public void A(String name); public void B(String name); public void C(String name); }
4.時我們的if else就變成 此時只需要把工廠名字作為參數傳進去即可調用對應的if邏輯,
好處就是 我們加一個if時 只需要加一個業務Handler實現Handler接口即可,不需要修改原來的if代碼,對擴展開放,對修改關閉
String name="1A"; Handler handler = Factory.getInvokeStrategy(name); handler.A(name);
第三步:使用模板方法繼續優化
上面第二步的HandlerA1實現Handler的時候 需要把Handler接口的所有方法全部實現
但是HanderA1並不需要B和C方法
我們改造Handler接口成一個抽象的AbstractHandler
public abstract class AbstractHandler implements InitializingBean { @Override public void afterPropertiesSet() throws Exception { } /*** * 用抽象類做模板方法 * @param name */ public void A(String name) { throw new UnsupportedOperationException(); } public void B(String name) { throw new UnsupportedOperationException(); } public void C(String name) { throw new UnsupportedOperationException(); } }
此時 我們的業務Handler繼承AbstractHandler然后還需要實現自己需要的業務方法即可
ClassLoader 調用findClass的過程就使用了模板方法的設計模式