直接干掉if-else,設(shè)計模式就是那么簡單

前言

傳統(tǒng)做法-if-else分支

策略模式+Map字典

責任鏈模式

策略模式+注解

小結(jié)

前言

在對接第三方接口中斟冕,通常會涉及到多個接口的報文(XML格式文件)傳輸和回執(zhí)接收口糕,每發(fā)送一份報文,后續(xù)都會收到與之關(guān)聯(lián)的回執(zhí)(標識該數(shù)據(jù)在第三方系統(tǒng)中的流轉(zhuǎn)狀態(tài))磕蛇。

這里枚舉幾種回執(zhí)類型:MT1101景描、MT2101、MT4101秀撇、MT8104超棺、MT8105、MT9999呵燕,系統(tǒng)在收到不同的回執(zhí)報文后棠绘,會執(zhí)行對應(yīng)的業(yè)務(wù)邏輯處理。當然再扭,實際業(yè)務(wù)場景并沒有那么籠統(tǒng)氧苍,這里以回執(zhí)處理為演示案例

模擬一個回執(zhí)類

@Data

public class Receipt {

? ? /**

? ? * 回執(zhí)信息

? ? */

? ? String message;

? ? /**

? ? * 回執(zhí)類型(`MT1101、MT2101泛范、MT4101让虐、MT8104、MT8105罢荡、MT9999`)

? ? */

? ? String type;

}

模擬一個回執(zhí)生成器

public class ReceiptBuilder {

? ? public static List<Receipt> generateReceiptList(){

? ? ? ? //直接模擬一堆回執(zhí)對象

? ? ? ? List<Receipt> receiptList = new ArrayList<>();

? ? ? ? receiptList.add(new Receipt("我是MT2101回執(zhí)喔","MT2101"));

? ? ? ? receiptList.add(new Receipt("我是MT1101回執(zhí)喔","MT1101"));

? ? ? ? receiptList.add(new Receipt("我是MT8104回執(zhí)喔","MT8104"));

? ? ? ? receiptList.add(new Receipt("我是MT9999回執(zhí)喔","MT9999"));

? ? ? ? //......

? ? ? ? return receiptList;

? ? }

}

傳統(tǒng)做法-if-else分支

List<Receipt> receiptList = ReceiptBuilder.generateReceiptList();

//循環(huán)處理

for (Receipt receipt : receiptList) {

? ? if (StringUtils.equals("MT2101",receipt.getType())) {

? ? ? ? System.out.println("接收到MT2101回執(zhí)");

? ? ? ? System.out.println("解析回執(zhí)內(nèi)容");

? ? ? ? System.out.println("執(zhí)行業(yè)務(wù)邏輯");

? ? } else if (StringUtils.equals("MT1101",receipt.getType())) {

? ? ? ? System.out.println("接收到MT1101回執(zhí)");

? ? ? ? System.out.println("解析回執(zhí)內(nèi)容");

? ? ? ? System.out.println("執(zhí)行業(yè)務(wù)邏輯");

? ? } else if (StringUtils.equals("MT8104",receipt.getType())) {

? ? ? ? System.out.println("接收到MT8104回執(zhí)");

? ? ? ? System.out.println("解析回執(zhí)內(nèi)容");

? ? ? ? System.out.println("執(zhí)行業(yè)務(wù)邏輯");

? ? } else if (StringUtils.equals("MT9999",receipt.getType())) {

? ? ? ? System.out.println("接收到MT9999回執(zhí)");

? ? ? ? System.out.println("解析回執(zhí)內(nèi)容");

? ? ? ? System.out.println("執(zhí)行業(yè)務(wù)邏輯");

? ? ? ? System.out.println("推送郵件");

? ? }

? ? // ......未來可能還有好多個else if

}

在遇到if-else的分支業(yè)務(wù)邏輯比較復(fù)雜時赡突,我們都習慣于將其抽出一個方法或者封裝成一個對象去調(diào)用,這樣整個if-else結(jié)構(gòu)就不會顯得太臃腫柠傍。

就上面例子麸俘,當回執(zhí)的類型越來越多時,分支else if 就會越來越多惧笛,每增加一個回執(zhí)類型从媚,就需要修改或添加if-else分支,違反了開閉原則(對擴展開放患整,對修改關(guān)閉)

策略模式+Map字典

我們知道拜效, 策略模式的目的是封裝一系列的算法,它們具有共性各谚,可以相互替換紧憾,也就是說讓算法獨立于使用它的客戶端而獨立變化,客戶端僅僅依賴于策略接口 昌渤。

在上述場景中赴穗,我們可以把if-else分支的業(yè)務(wù)邏輯抽取為各種策略,但是不可避免的是依然需要客戶端寫一些if-else進行策略選擇的邏輯,我們可以將這段邏輯抽取到工廠類中去般眉,這就是策略模式+簡單工廠了赵,代碼如下

策略接口

/**

* @Description: 回執(zhí)處理策略接口

* @Auther: wuzhazha

*/

public interface IReceiptHandleStrategy {

? ? void handleReceipt(Receipt receipt);

}

策略接口實現(xiàn)類,也就是具體的處理者

public class Mt2101ReceiptHandleStrategy implements IReceiptHandleStrategy {

? ? @Override

? ? public void handleReceipt(Receipt receipt) {

? ? ? ? System.out.println("解析報文MT2101:" + receipt.getMessage());

? ? }

}

public class Mt1101ReceiptHandleStrategy implements IReceiptHandleStrategy {

? ? @Override

? ? public void handleReceipt(Receipt receipt) {

? ? ? ? System.out.println("解析報文MT1101:" + receipt.getMessage());

? ? }

}

public class Mt8104ReceiptHandleStrategy implements IReceiptHandleStrategy {

? ? @Override

? ? public void handleReceipt(Receipt receipt) {

? ? ? ? System.out.println("解析報文MT8104:" + receipt.getMessage());

? ? }

}

public class Mt9999ReceiptHandleStrategy implements IReceiptHandleStrategy {

? ? @Override

? ? public void handleReceipt(Receipt receipt) {

? ? ? ? System.out.println("解析報文MT9999:" + receipt.getMessage());

? ? }

}


策略上下文類(策略接口的持有者)

/**

* @Description: 上下文類甸赃,持有策略接口

* @Auther: wuzhazha

*/

public class ReceiptStrategyContext {

? ? private IReceiptHandleStrategy receiptHandleStrategy;

? ? /**

? ? * 設(shè)置策略接口

? ? * @param receiptHandleStrategy

? ? */

? ? public void setReceiptHandleStrategy(IReceiptHandleStrategy receiptHandleStrategy) {

? ? ? ? this.receiptHandleStrategy = receiptHandleStrategy;

? ? }

? ? public void handleReceipt(Receipt receipt){

? ? ? ? if (receiptHandleStrategy != null) {

? ? ? ? receiptHandleStrategy.handleReceipt(receipt);

? ? ? ? }

? ? }

}

策略工廠

/**

* @Description: 策略工廠

* @Auther: wuzhazha

*/

public class ReceiptHandleStrategyFactory {

? ? private ReceiptHandleStrategyFactory(){}

? ? public static IReceiptHandleStrategy getReceiptHandleStrategy(String receiptType){

? ? ? ? IReceiptHandleStrategy receiptHandleStrategy = null;

? ? ? ? if (StringUtils.equals("MT2101",receiptType)) {

? ? ? ? ? ? receiptHandleStrategy = new Mt2101ReceiptHandleStrategy();

? ? ? ? } else if (StringUtils.equals("MT8104",receiptType)) {

? ? ? ? ? ? receiptHandleStrategy = new Mt8104ReceiptHandleStrategy();

? ? ? ? }

? ? ? ? return receiptHandleStrategy;

? ? }

}


客戶端

public class Client {

? ? public static void main(String[] args) {

? ? ? ? //模擬回執(zhí)

? ? ? ? List<Receipt> receiptList = ReceiptBuilder.generateReceiptList();

? ? ? ? //策略上下文

? ? ? ? ReceiptStrategyContext receiptStrategyContext = new ReceiptStrategyContext();

? ? ? ? for (Receipt receipt : receiptList) {

? ? ? ? ? ? //獲取并設(shè)置策略

? ? ? ? ? ? IReceiptHandleStrategy receiptHandleStrategy = ReceiptHandleStrategyFactory.getReceiptHandleStrategy(receipt.getType());

? ? ? ? ? ? receiptStrategyContext.setReceiptHandleStrategy(receiptHandleStrategy);

? ? ? ? ? ? //執(zhí)行策略

? ? ? ? ? ? receiptStrategyContext.handleReceipt(receipt);

? ? ? ? }

? ? }

}


解析報文MT2101:我是MT2101回執(zhí)報文喔 解析報文MT8104:我是MT8104回執(zhí)報文喔

由于我們的目的是消除if-else柿汛,那么這里需要將ReceiptHandleStrategyFactory策略工廠進行改造下,采用字典的方式存放我的策略埠对,而Map具備key-value結(jié)構(gòu)络断,采用Map是個不錯選擇。

稍微改造下项玛,代碼如下

/**

* @Description: 策略工廠

* @Auther: wuzhazha

*/

public class ReceiptHandleStrategyFactory {

? ? private static Map<String,IReceiptHandleStrategy> receiptHandleStrategyMap;

? ? private ReceiptHandleStrategyFactory(){

? ? ? ? this.receiptHandleStrategyMap = new HashMap<>();

? ? ? ? this.receiptHandleStrategyMap.put("MT2101",new Mt2101ReceiptHandleStrategy());

? ? ? ? this.receiptHandleStrategyMap.put("MT8104",new Mt8104ReceiptHandleStrategy());

? ? }

? ? public static IReceiptHandleStrategy getReceiptHandleStrategy(String receiptType){

? ? ? ? return receiptHandleStrategyMap.get(receiptType);

? ? }

}


經(jīng)過對策略模式+簡單工廠方案的改造貌笨,我們已經(jīng)消除了if-else的結(jié)構(gòu),每當新來了一種回執(zhí)稍计,只需要添加新的回執(zhí)處理策略躁绸,并修改ReceiptHandleStrategyFactory中的Map集合。

如果要使得程序符合開閉原則臣嚣,則需要調(diào)整ReceiptHandleStrategyFactory中處理策略的獲取方式净刮,通過反射的方式,獲取指定包下的所有IReceiptHandleStrategy實現(xiàn)類硅则,然后放到字典Map中去淹父。

責任鏈模式

責任鏈模式是一種對象的行為模式。在責任鏈模式里怎虫,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈暑认。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求大审。

發(fā)出這個請求的客戶端并不知道鏈上的哪一個對象最終處理這個請求蘸际,這使得系統(tǒng)可以在不影響客戶端的情況下動態(tài)地重新組織和分配責任

回執(zhí)處理者接口

/**

* @Description: 抽象回執(zhí)處理者接口

* @Auther: wuzhazha

*/

public interface IReceiptHandler {

? ? void handleReceipt(Receipt receipt,IReceiptHandleChain handleChain);

}

責任鏈接口

/**

* @Description: 責任鏈接口

* @Auther: wuzhazha

*/

public interface IReceiptHandleChain {

? ? void handleReceipt(Receipt receipt);

}

責任鏈接口實現(xiàn)類

/**

* @Description: 責任鏈實現(xiàn)類

* @Auther: wuzhazha

*/

public class ReceiptHandleChain implements IReceiptHandleChain {

//記錄當前處理者位置

? ? private int index = 0;

? ? //處理者集合

? ? private static List<IReceiptHandler> receiptHandlerList;

? ? static {

? ? ? ? //從容器中獲取處理器對象

? ? ? ? receiptHandlerList = ReceiptHandlerContainer.getReceiptHandlerList();

? ? }

? ? @Override

? ? public void handleReceipt(Receipt receipt) {

? ? ? ? if (receiptHandlerList !=null && receiptHandlerList.size() > 0) {

? ? ? ? ? ? if (index != receiptHandlerList.size()) {

? ? ? ? ? ? ? ? IReceiptHandler receiptHandler = receiptHandlerList.get(index++);

? ? ? ? ? ? ? ? receiptHandler.handleReceipt(receipt,this);

? ? ? ? ? ? }

? ? ? ? }

? ? }

}


具體回執(zhí)處理者

public class Mt2101ReceiptHandler implements IReceiptHandler {

? ? @Override

? ? public void handleReceipt(Receipt receipt, IReceiptHandleChain handleChain) {

? ? ? ? if (StringUtils.equals("MT2101",receipt.getType())) {

? ? ? ? ? ? System.out.println("解析報文MT2101:" + receipt.getMessage());

? ? ? ? }

? ? ? ? //處理不了該回執(zhí)就往下傳遞

? ? ? ? else {? ? ? ?

? ? ? ? ? ? handleChain.handleReceipt(receipt);

? ? ? ? }

? ? }

}

public class Mt8104ReceiptHandler implements IReceiptHandler {

? ? @Override

? ? public void handleReceipt(Receipt receipt, IReceiptHandleChain handleChain) {

? ? ? ? if (StringUtils.equals("MT8104",receipt.getType())) {

? ? ? ? ? ? System.out.println("解析報文MT8104:" + receipt.getMessage());

? ? ? ? }

? ? ? ? //處理不了該回執(zhí)就往下傳遞

? ? ? ? else {

? ? ? ? ? ? handleChain.handleReceipt(receipt);

? ? ? ? }

? ? }

}


責任鏈處理者容器(如果采用spring,則可以通過依賴注入的方式獲取到IReceiptHandler的子類對象)

/**

* @Description: 處理者容器

* @Auther: wuzhazha

*/

public class ReceiptHandlerContainer {

? ? private ReceiptHandlerContainer(){}

? ? public static List<IReceiptHandler> getReceiptHandlerList(){

? ? ? ? List<IReceiptHandler> receiptHandlerList = new ArrayList<>();

? ? ? ? receiptHandlerList.add(new Mt2101ReceiptHandler());

? ? ? ? receiptHandlerList.add(new Mt8104ReceiptHandler());

? ? ? ? return receiptHandlerList;

? ? }

}


客戶端

public class Client {

? ? public static void main(String[] args) {

? ? ? ? //模擬回執(zhí)

? ? ? ? List<Receipt> receiptList = ReceiptBuilder.generateReceiptList();

? ? ? ? for (Receipt receipt : receiptList) {

? ? ? ? ? ? //回執(zhí)處理鏈對象

? ? ? ? ? ? ReceiptHandleChain receiptHandleChain = new ReceiptHandleChain();

? ? ? ? ? ? receiptHandleChain.handleReceipt(receipt);

? ? ? ? }

? ? }

}


解析報文MT2101:我是MT2101回執(zhí)報文喔 解析報文MT8104:我是MT8104回執(zhí)報文喔

通過責任鏈的處理方式,if-else結(jié)構(gòu)也被我們消除了徒扶,每當新來了一種回執(zhí)粮彤,只需要添加IReceiptHandler實現(xiàn)類并修改ReceiptHandlerContainer處理者容器即可,如果要使得程序符合開閉原則姜骡,則需要調(diào)整ReceiptHandlerContainer中處理者的獲取方式导坟,通過反射的方式,獲取指定包下的所有IReceiptHandler實現(xiàn)類圈澈。

這里使用到了一個反射工具類惫周,用于獲取指定接口的所有實現(xiàn)類

/**

* @Description: 反射工具類

* @Auther: wuzhazha

*/

public class ReflectionUtil {


? ? /**

? ? * 定義類集合(用于存放所有加載的類)

? ? */

? ? private static final Set<Class<?>> CLASS_SET;

? ? static {

? ? ? ? //指定加載包路徑

? ? ? ? CLASS_SET = getClassSet("com.yaolong");

? ? }


? ? /**

? ? * 獲取類加載器

? ? * @return

? ? */

? ? public static ClassLoader getClassLoader(){

? ? ? ? return Thread.currentThread().getContextClassLoader();

? ? }

? ? /**

? ? * 加載類

? ? * @param className 類全限定名稱

? ? * @param isInitialized 是否在加載完成后執(zhí)行靜態(tài)代碼塊

? ? * @return

? ? */

? ? public static Class<?> loadClass(String className,boolean isInitialized) {

? ? ? ? Class<?> cls;

? ? ? ? try {

? ? ? ? ? ? cls = Class.forName(className,isInitialized,getClassLoader());

? ? ? ? } catch (ClassNotFoundException e) {

? ? ? ? ? ? throw new RuntimeException(e);

? ? ? ? }

? ? ? ? return cls;

? ? }

? ? public static Class<?> loadClass(String className) {

? ? ? ? return loadClass(className,true);

? ? }

? ? /**

? ? * 獲取指定包下所有類

? ? * @param packageName

? ? * @return

? ? */

? ? public static Set<Class<?>> getClassSet(String packageName) {

? ? ? ? Set<Class<?>> classSet = new HashSet<>();

? ? ? ? try {

? ? ? ? ? ? Enumeration<URL> urls = getClassLoader().getResources(packageName.replace(".","/"));

? ? ? ? ? ? while (urls.hasMoreElements()) {

? ? ? ? ? ? ? ? URL url = urls.nextElement();

? ? ? ? ? ? ? ? if (url != null) {

? ? ? ? ? ? ? ? ? ? String protocol = url.getProtocol();

? ? ? ? ? ? ? ? ? ? if (protocol.equals("file")) {

? ? ? ? ? ? ? ? ? ? ? ? String packagePath = url.getPath().replace("%20","");

? ? ? ? ? ? ? ? ? ? ? ? addClass(classSet,packagePath,packageName);

? ? ? ? ? ? ? ? ? ? } else if (protocol.equals("jar")) {

? ? ? ? ? ? ? ? ? ? ? ? JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();

? ? ? ? ? ? ? ? ? ? ? ? if (jarURLConnection != null) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? JarFile jarFile = jarURLConnection.getJarFile();

? ? ? ? ? ? ? ? ? ? ? ? ? ? if (jarFile != null) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Enumeration<JarEntry> jarEntries = jarFile.entries();

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? while (jarEntries.hasMoreElements()) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? JarEntry jarEntry = jarEntries.nextElement();

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? String jarEntryName = jarEntry.getName();

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (jarEntryName.endsWith(".class")) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? doAddClass(classSet,className);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? } catch (IOException e) {

? ? ? ? ? ? throw new RuntimeException(e);

? ? ? ? }

? ? ? ? return classSet;

? ? }

? ? private static void doAddClass(Set<Class<?>> classSet, String className) {

? ? ? ? Class<?> cls = loadClass(className,false);

? ? ? ? classSet.add(cls);

? ? }

? ? private static void addClass(Set<Class<?>> classSet, String packagePath, String packageName) {

? ? ? ? final File[] files = new File(packagePath).listFiles(new FileFilter() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public boolean accept(File file) {

? ? ? ? ? ? ? ? return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? for (File file : files) {

? ? ? ? ? ? String fileName = file.getName();

? ? ? ? ? ? if (file.isFile()) {

? ? ? ? ? ? ? ? String className = fileName.substring(0, fileName.lastIndexOf("."));

? ? ? ? ? ? ? ? if (StringUtils.isNotEmpty(packageName)) {

? ? ? ? ? ? ? ? ? ? className = packageName + "." + className;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? doAddClass(classSet,className);

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? String subPackagePath = fileName;

? ? ? ? ? ? ? ? if (StringUtils.isNotEmpty(packagePath)) {

? ? ? ? ? ? ? ? ? ? subPackagePath = packagePath + "/" + subPackagePath;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? String subPackageName = fileName;

? ? ? ? ? ? ? ? if (StringUtils.isNotEmpty(packageName)) {

? ? ? ? ? ? ? ? ? ? subPackageName = packageName + "." + subPackageName;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? addClass(classSet,subPackagePath,subPackageName);

? ? ? ? ? ? }

? ? ? ? }

? ? }

? ? public static Set<Class<?>> getClassSet() {

? ? ? ? return CLASS_SET;

? ? }

? ? /**

? ? * 獲取應(yīng)用包名下某父類(或接口)的所有子類(或?qū)崿F(xiàn)類)

? ? * @param superClass

? ? * @return

? ? */

? ? public static Set<Class<?>> getClassSetBySuper(Class<?> superClass) {

? ? ? ? Set<Class<?>> classSet = new HashSet<>();

? ? ? ? for (Class<?> cls : CLASS_SET) {

? ? ? ? ? ? if (superClass.isAssignableFrom(cls) && !superClass.equals(cls)) {

? ? ? ? ? ? ? ? classSet.add(cls);

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return classSet;

? ? }

? ? /**

? ? * 獲取應(yīng)用包名下帶有某注解的類

? ? * @param annotationClass

? ? * @return

? ? */

? ? public static Set<Class<?>> getClassSetByAnnotation(Class<? extends Annotation> annotationClass) {

? ? ? ? Set<Class<?>> classSet = new HashSet<>();

? ? ? ? for (Class<?> cls : CLASS_SET) {

? ? ? ? ? ? if (cls.isAnnotationPresent(annotationClass)) {

? ? ? ? ? ? ? ? classSet.add(cls);

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return classSet;

? ? }

}


接下來改造ReceiptHandlerContainer

public class ReceiptHandlerContainer {

? ? private ReceiptHandlerContainer(){}

? ? public static List<IReceiptHandler> getReceiptHandlerList(){

? ? ? ? List<IReceiptHandler> receiptHandlerList = new ArrayList<>();

? ? ? ? //獲取IReceiptHandler接口的實現(xiàn)類

? ? ? ? Set<Class<?>> classList = ReflectionUtil.getClassSetBySuper(IReceiptHandler.class);

? ? ? ? if (classList != null && classList.size() > 0) {

? ? ? ? ? ? for (Class<?> clazz : classList) {

? ? ? ? ? ? ? ? try {

? ? ? ? ? ? ? ? ? ? receiptHandlerList.add((IReceiptHandler)clazz.newInstance());

? ? ? ? ? ? ? ? } catch ( Exception e) {

? ? ? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return receiptHandlerList;

? ? }

}


至此,該方案完美符合了開閉原則康栈,如果新增一個回執(zhí)類型递递,只需要添加一個新的回執(zhí)處理器即可喷橙,無需做其它改動。如新加了MT6666的回執(zhí)漾狼,代碼如下

public class Mt6666ReceiptHandler implements IReceiptHandler {

? ? @Override

? ? public void handleReceipt(Receipt receipt, IReceiptHandleChain handleChain) {

? ? ? ? if (StringUtils.equals("MT6666",receipt.getType())) {

? ? ? ? ? ? System.out.println("解析報文MT6666:" + receipt.getMessage());

? ? ? ? }

? ? ? ? //處理不了該回執(zhí)就往下傳遞

? ? ? ? else {

? ? ? ? ? ? handleChain.handleReceipt(receipt);

? ? ? ? }

? ? }

}


策略模式+注解

此方案其實和上述沒有太大異同重慢,為了能符合開閉原則饥臂,通過自定義注解的方式逊躁,標記處理者類,然后反射獲取到該類集合隅熙,放到Map容器中稽煤,這里不再贅述

小結(jié)

if-else或switch case 這種分支判斷的方式對于分支邏輯不多的簡單業(yè)務(wù),還是直觀高效的囚戚。對于業(yè)務(wù)復(fù)雜酵熙,分支邏輯多,采用適當?shù)哪J郊记沙鄯唬瑫尨a更加清晰匾二,容易維護,但同時類或方法數(shù)量也是倍增的拳芙。我們需要對業(yè)務(wù)做好充分分析察藐,避免一上來就設(shè)計模式,避免過度設(shè)計舟扎!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末分飞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子睹限,更是在濱河造成了極大的恐慌譬猫,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件羡疗,死亡現(xiàn)場離奇詭異染服,居然都是意外死亡,警方通過查閱死者的電腦和手機叨恨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門柳刮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人特碳,你說我怎么就攤上這事诚亚。” “怎么了午乓?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵站宗,是天一觀的道長。 經(jīng)常有香客問我益愈,道長梢灭,這世上最難降的妖魔是什么夷家? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮敏释,結(jié)果婚禮上库快,老公的妹妹穿的比我還像新娘。我一直安慰自己钥顽,他們只是感情好义屏,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蜂大,像睡著了一般闽铐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奶浦,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天兄墅,我揣著相機與錄音,去河邊找鬼澳叉。 笑死隙咸,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的成洗。 我是一名探鬼主播五督,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼泌枪!你這毒婦竟也來了概荷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤碌燕,失蹤者是張志新(化名)和其女友劉穎误证,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體修壕,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡愈捅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了慈鸠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓝谨。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖青团,靈堂內(nèi)的尸體忽然破棺而出譬巫,到底是詐尸還是另有隱情,我是刑警寧澤督笆,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布芦昔,位于F島的核電站,受9級特大地震影響娃肿,放射性物質(zhì)發(fā)生泄漏咕缎。R本人自食惡果不足惜珠十,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望凭豪。 院中可真熱鬧焙蹭,春花似錦、人聲如沸嫂伞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽末早。三九已至烟馅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間然磷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工刊驴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留姿搜,地道東北人。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓捆憎,卻偏偏與公主長得像舅柜,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子躲惰,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容