来吧,用设计模式来干掉 if-else( 四 )

责任链处理者容器(如果采用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) {        //模拟回执        List<Receipt> receiptList = ReceiptBuilder.generateReceiptList();        for (Receipt receipt : receiptList) {            //回执处理链对象            ReceiptHandleChain receiptHandleChain = new ReceiptHandleChain();            receiptHandleChain.handleReceipt(receipt);        }    }}

解析报文MT2101:我是MT2101回执报文喔解析报文MT8104:我是MT8104回执报文喔
通过责任链的处理方式 , if-else结构也被我们消除了 , 每当新来了一种回执 , 只需要添加IReceiptHandler实现类并修改ReceiptHandlerContainer处理者容器即可 , 如果要使得程序符合开闭原则 , 则需要调整ReceiptHandlerContainer中处理者的获取方式 , 通过反射的方式 , 获取指定包下的所有IReceiptHandler实现类 。JAVA知音公众号内回复“后端面试” , 送你一份面试宝典
这里使用到了一个反射工具类 , 用于获取指定接口的所有实现类
/** * @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 是否在加载完成后执行静态代码块     * @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;    }    /**     * 获取应用包名下某父类(或接口)的所有子类(或实现类)     * @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;    }    /**     * 获取应用包名下带有某注解的类     * @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;    }}


推荐阅读