Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >来吧,用设计模式来干掉 if-else

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

作者头像
用户5224393
发布于 2020-07-09 07:45:42
发布于 2020-07-09 07:45:42
3.5K00
代码可运行
举报
文章被收录于专栏:Java研发军团Java研发军团
运行总次数:0
代码可运行

作者:DiDi516 cnblogs.com/DiDi516/p/11787257.html

前言

物流行业中,通常会涉及到EDI报文(XML格式文件)传输和回执接收,每发送一份EDI报文,后续都会收到与之关联的回执(标识该数据在第三方系统中的流转状态)。

这里枚举几种回执类型:MT1101、MT2101、MT4101、MT8104、MT8105、MT9999,系统在收到不同的回执报文后,会执行对应的业务逻辑处理。当然,实际业务场景并没有那么笼统,这里以回执处理为演示案例

模拟一个回执类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Data
public class Receipt {

    /**
     * 回执信息
     */
    String message;

    /**
     * 回执类型(`MT1101、MT2101、MT4101、MT8104、MT8105、MT9999`)
     */
    String type;

}

模拟一个回执生成器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ReceiptBuilder {

    public static List<Receipt> generateReceiptList(){
        //直接模拟一堆回执对象
        List<Receipt> receiptList = new ArrayList<>();
        receiptList.add(new Receipt("我是MT2101回执喔","MT2101"));
        receiptList.add(new Receipt("我是MT1101回执喔","MT1101"));
        receiptList.add(new Receipt("我是MT8104回执喔","MT8104"));
        receiptList.add(new Receipt("我是MT9999回执喔","MT9999"));
        //......    
        return receiptList;
    }
}

传统做法-if-else分支

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
List<Receipt> receiptList = ReceiptBuilder.generateReceiptList();
//循环处理
for (Receipt receipt : receiptList) {
    if (StringUtils.equals("MT2101",receipt.getType())) {
        System.out.println("接收到MT2101回执");
        System.out.println("解析回执内容");
        System.out.println("执行业务逻辑");
    } else if (StringUtils.equals("MT1101",receipt.getType())) {
        System.out.println("接收到MT1101回执");
        System.out.println("解析回执内容");
        System.out.println("执行业务逻辑");
    } else if (StringUtils.equals("MT8104",receipt.getType())) {
        System.out.println("接收到MT8104回执");
        System.out.println("解析回执内容");
        System.out.println("执行业务逻辑");
    } else if (StringUtils.equals("MT9999",receipt.getType())) {
        System.out.println("接收到MT9999回执");
        System.out.println("解析回执内容");
        System.out.println("执行业务逻辑");
        System.out.println("推送邮件");
    }
    // ......未来可能还有好多个else if
}

在遇到if-else的分支业务逻辑比较复杂时,我们都习惯于将其抽出一个方法或者封装成一个对象去调用,这样整个if-else结构就不会显得太臃肿。

就上面例子,当回执的类型越来越多时,分支else if 就会越来越多,每增加一个回执类型,就需要修改或添加if-else分支,违反了开闭原则(对扩展开放,对修改关闭)

策略模式+Map字典

我们知道, 策略模式的目的是封装一系列的算法,它们具有共性,可以相互替换,也就是说让算法独立于使用它的客户端而独立变化,客户端仅仅依赖于策略接口 。

在上述场景中,我们可以把if-else分支的业务逻辑抽取为各种策略,但是不可避免的是依然需要客户端写一些if-else进行策略选择的逻辑,我们可以将这段逻辑抽取到工厂类中去,这就是策略模式+简单工厂,代码如下

策略接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @Description: 回执处理策略接口
 * @Auther: wuzhazha
 */
public interface IReceiptHandleStrategy {

    void handleReceipt(Receipt receipt);

}

策略接口实现类,也就是具体的处理者

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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());
    }

}

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @Description: 上下文类,持有策略接口
 * @Auther: wuzhazha
 */
public class ReceiptStrategyContext {

    private IReceiptHandleStrategy receiptHandleStrategy;

    /**
     * 设置策略接口
     * @param receiptHandleStrategy
     */
    public void setReceiptHandleStrategy(IReceiptHandleStrategy receiptHandleStrategy) {
        this.receiptHandleStrategy = receiptHandleStrategy;
    }

    public void handleReceipt(Receipt receipt){
        if (receiptHandleStrategy != null) {
             receiptHandleStrategy.handleReceipt(receipt);   
        }
    }
}

策略工厂

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @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;
    }
}

客户端

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Client {

    public static void main(String[] args) {
        //模拟回执
        List<Receipt> receiptList = ReceiptBuilder.generateReceiptList();
        //策略上下文
        ReceiptStrategyContext receiptStrategyContext = new ReceiptStrategyContext();
        for (Receipt receipt : receiptList) {
            //获取并设置策略
            IReceiptHandleStrategy receiptHandleStrategy = ReceiptHandleStrategyFactory.getReceiptHandleStrategy(receipt.getType());
            receiptStrategyContext.setReceiptHandleStrategy(receiptHandleStrategy);
            //执行策略
            receiptStrategyContext.handleReceipt(receipt);
        }
    }
}

解析报文MT2101:我是MT2101回执报文喔 解析报文MT8104:我是MT8104回执报文喔

由于我们的目的是消除if-else,那么这里需要将ReceiptHandleStrategyFactory策略工厂进行改造下,采用字典的方式存放我的策略,而Map具备key-value结构,采用Map是个不错选择。

稍微改造下,代码如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @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);
    }
}

经过对策略模式+简单工厂方案的改造,我们已经消除了if-else的结构,每当新来了一种回执,只需要添加新的回执处理策略,并修改ReceiptHandleStrategyFactory中的Map集合。

如果要使得程序符合开闭原则,则需要调整ReceiptHandleStrategyFactory中处理策略的获取方式,通过反射的方式,获取指定包下的所有IReceiptHandleStrategy实现类,然后放到字典Map中去。

责任链模式

责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。

发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任

回执处理者接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @Description: 抽象回执处理者接口
 * @Auther: wuzhazha
 */
public interface IReceiptHandler {

    void handleReceipt(Receipt receipt,IReceiptHandleChain handleChain);

}

责任链接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @Description: 责任链接口
 * @Auther: wuzhazha
 */
public interface IReceiptHandleChain {

    void handleReceipt(Receipt receipt);
}

责任链接口实现类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @Description: 责任链实现类
 * @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);
            }
        }
    }
}

具体回执处理者

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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());
        } 
        //处理不了该回执就往下传递
        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());
        }
        //处理不了该回执就往下传递
        else {
            handleChain.handleReceipt(receipt);
        }
    }
}

责任链处理者容器(如果采用spring,则可以通过依赖注入的方式获取到IReceiptHandler的子类对象)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @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;
    }

}

客户端

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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知音公众号内回复“后端面试”,送你一份面试宝典

这里使用到了一个反射工具类,用于获取指定接口的所有实现类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @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;
    }

}

接下来改造ReceiptHandlerContainer

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ReceiptHandlerContainer {

    private ReceiptHandlerContainer(){}

    public static List<IReceiptHandler> getReceiptHandlerList(){
        List<IReceiptHandler> receiptHandlerList = new ArrayList<>();
        //获取IReceiptHandler接口的实现类
        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;
    }

}

至此,该方案完美符合了开闭原则,如果新增一个回执类型,只需要添加一个新的回执处理器即可,无需做其它改动。如新加了MT6666的回执,代码如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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());
        }
        //处理不了该回执就往下传递
        else {
            handleChain.handleReceipt(receipt);
        }
    }
}

策略模式+注解

此方案其实和上述没有太大异同,为了能符合开闭原则,通过自定义注解的方式,标记处理者类,然后反射获取到该类集合,放到Map容器中,这里不再赘述

小结

if-else或switch case 这种分支判断的方式对于分支逻辑不多的简单业务,还是直观高效的。对于业务复杂,分支逻辑多,采用适当的模式技巧,会让代码更加清晰,容易维护,但同时类或方法数量也是倍增的。我们需要对业务做好充分分析,避免一上来就设计模式,避免过度设计!

推荐前后端分离后台管理系统实战

登陆界面

首页

富文本编辑器

md编辑器

图表

表格

上述系统方案作为一套多功能的后台框架模板,适用于绝大部分的后台管理系统(Web Management System)开发。基于 vue.js,使用 vue-cli3 脚手架,引用 Element UI 组件库,方便开发快速简洁好看的组件。分离颜色样式,支持手动切换主题色,而且很方便使用自定义主题色。

这套前端系统是相当干净的,也非常简单,大家后台可以用自己较为熟悉的后端就可以直接对接,写出自己任意的后台管理系统了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java研发军团 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
策略模式解决多重if-else
使用策略模式解决多重if-else 参考学习资料: https://www.cnblogs.com/adamjwh/p/11011095.html https://mp.weixin.qq.com/s/P0G8YHY3kQHJ90NyrOrmOA 最近现在项目开发中遇到公众号发送模板消息。项目经理申请了很多种模板发送消息给关注着。如果不使用设计模式需要使用switch 或者if-else 造成 代码臃肿。看到一篇使用策略模式+工厂+字典map 解决多重if-else 。分享给大家。相互学习。有什么不
全栈程序员站长
2021/07/14
6230
自己写个类加载器
获取指定包下所有的类,需要将包名转换为文件路径,读class文件或者jar包,再去进行类加载:
春哥大魔王
2018/07/23
4560
自己写个类加载器
@Compenent,@Autowired,@PostConstruct自实现
本来是想为安卓开发一套可以依赖注入的标签,但是发现安卓很难找到选定包内的java或者class文件。所以只能当做学习参考了,全套代码如下
算法之名
2019/08/20
7520
如何用策略模式干掉 if-else
日常编码过程中遇到很多的 if-else ,代码扩展性和阅读性会受到影响,代码中常常使用策略模式代替 if-else
王小明_HIT
2022/06/14
4250
if-else泛滥成灾?这样优雅去掉后更简洁了!【粉丝答疑】
前段时间,和大家分享了一个关于如何优雅使用if-else的文章,之后陆陆续续好几个小伙伴微信给我留言聊最后那一段,说没有看明白,那么今天就来针对性的整理一下;答应粉丝的事情,必须得完成的。
一行Java
2022/04/07
5820
if-else泛滥成灾?这样优雅去掉后更简洁了!【粉丝答疑】
面试官问我咋实现Spring框架IOC和DI好吧打趴下,深度解析手动实现Spring框架的IOC与DI功能
面试官问我咋实现Spring框架IOC和DI好吧打趴下,深度解析手动实现Spring框架的IOC与DI功能
杨不易呀
2023/09/26
4340
面试官问我咋实现Spring框架IOC和DI好吧打趴下,深度解析手动实现Spring框架的IOC与DI功能
解析反射 顶
反射离不开Class.forName(),我们先从Class.forName说起。
算法之名
2019/08/20
6070
解析反射
                                                                            顶
【玩烂设计模式】设计模式之策略模式
什么是策略模式 策略模式就是定义了算法家族 分别封装起来 让它们之间互相替换 从模式让算法的变化 不会影响到使用算法的客户。
周杰伦本人
2022/10/25
3900
【玩烂设计模式】设计模式之策略模式
策略设计模式以及其应用(消除if-else)
消除if-else,将每种情况的具体实现封装到具体实现策略类中,而常量选择代码则封装到策略工厂中。
Java微观世界
2025/01/20
1210
根据路径获取指定类实例并执行指定的方法
“ 最近在OA项目上和第三方做集成,我需要提供一些接口给供第三方调用,在这个过程中觉得自己测试接口很麻烦,所以想写一个JSP界面来界面化测试自己写的一些接口。”
每天学Java
2020/06/02
2.9K0
用简单代码实现IOC容器
相信每一个java程序员在面试经历中,都被面试官问到过AOP和IOC,用官方的话语来回答AOP和IOC,那就是切面编程和控制反转及依赖注入。
Java3y
2019/05/08
7030
用简单代码实现IOC容器
Java设计模式之(十四)——策略模式
策略模式(Strategy Pattern):定义一族算法类,将每个算法分别封装起来,让它们可以互相替换。
IT可乐
2021/12/04
4160
Java设计模式之(十四)——策略模式
重生之设计模式:策略模式
在软件开发中,我们常常会遇到这样的场景:​同一个功能需要根据不同的条件选择不同的算法或行为。例如:
HandsomeYo
2025/04/03
730
重生之设计模式:策略模式
大话设计模式--第二章 策略设计模式
现在有一个需求: 给商场做一个收银软件. 营业员根据客户购买的产品的单价和数量, 向客户打印小票。
用户7798898
2020/09/27
1.4K0
大话设计模式--第二章 策略设计模式
设计模式-策略模式
一个类的行为或其算法可以在运行时更改,我们把它降维到代码层面。 用人话翻译一下就是,运行时我给你这个类的方法传不同的“key”,你这个方法会执行不同的业务逻辑。 细品一下,这不就是 if else 干的事吗?
才疏学浅的木子
2024/04/15
1560
设计模式-策略模式
手写Springmvc
通过解析xml获取扫包范围,通过扫包范围工具类,找打类上是否有controller注解,并将其装入容器中。再看类上是否有requestMapping ,创建类与url的关系,再检查该类方法中是否有requestMapping是否存在注解,并且创建方法与url的关系。
斯文的程序
2019/11/07
7010
velocity笔记(一)什么是velocity,我们什么时候会使用到这个,基本语法,利用模板生成实体类的各层代码
也就是前端程序员写velocity模板,后端程序员写数据模型,最后整合就是展示给用户的东西
一写代码就开心
2022/05/09
1.1K0
velocity笔记(一)什么是velocity,我们什么时候会使用到这个,基本语法,利用模板生成实体类的各层代码
8种优化if-else代码的方案请拿走
代码中如果if-else比较多,阅读起来比较困难,维护起来也比较困难,很容易出bug,接下来,本文将介绍优化if-else代码的八种方案。
用户4172423
2020/03/12
1.4K0
使用策略模式重构电商折扣和支付场景
大家都知道,咕泡学院的架构师课程经常会有优惠活动,优惠策略有很多种可能,如领取优惠券抵扣、返现促销、拼团优惠等。下面用代码来模拟,首先创建一个促销策略的抽象PromotionStrategy。
Tom弹架构
2021/11/05
7240
设计模式-策略模式
每当想起去书店买书,老是觉得老火,为啥同样一本书,卖我总是比别人贵呢?我买就只打8折为啥其他有7折的???人品问题???不是的,是因为会员制度,不同的会员等级享受不同的折扣,这个很类似我们的策略模式,不同的角色可以定义不同的算法。
逍遥壮士
2020/09/18
4550
设计模式-策略模式
推荐阅读
相关推荐
策略模式解决多重if-else
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验