还在用if?设计模式加容器思想进行代码优化确定不了解一下?

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 平常的开发工作中同一个业务不同的场景一般是采用不同的处理方式,如何根据不同的场景进行不同的业务实现,if else一定是处理此类问题的万能钥匙,不管多少分支,if绝对管够。这种处理方式确实万能,但是这么肆无忌惮的怼上这么多if总感觉不太优雅,下面就结合实际的业务场景说下如何优化此类问题。

前言


   平常的开发工作中同一个业务不同的场景一般是采用不同的处理方式,如何根据不同的场景进行不同的业务实现,if else一定是处理此类问题的万能钥匙,不管多少分支,if绝对管够。这种处理方式确实万能,但是这么肆无忌惮的怼上这么多if总感觉不太优雅,下面就结合实际的业务场景说下如何优化此类问题。

   现在有一个营销活动支付场景,各种营销活动都是在支付成功的回调中进行对应的业务处理,现在需要实现的是分销活动、拼团活动,后期还会增加其他的活动类型,不同的活动处理逻辑不同。支付成功回调中最初的实现伪代码如下:

if(活动id=11){
    // 执行分销活动的业务处理逻辑
}
if(活动id=12){
    // 执行拼团活动的业务处理逻辑
}
  // 其他营销活动....


下面就结合实际场景进行优化。


代码优化


优化1:工厂模式+策略模式代替万能if

    活动类型与活动处理类做映射关系处理,根据活动类型获取活动处理类,然后执行对应活动业务处理。将活动类型与活动处理类组成key-value形式封装成map组合,每次根据活动类型获取对应的活动类型处理类。

    先说策略模式,官方介绍不说了,通俗易懂的说下自己的理解:对于多种活动实现而言,需要有一个公共的业务实现方法,每种活动的具体处理逻辑由子类或是实现类进行处理。公共的业务实现方法一般在父类或是抽象类中,具体的业务由子类或是实现类处理。对应代码说下上面的两种关系:

    活动处理顶级父类,提供活动处理的公共逻辑:

public abstract class AbstractActivity {
    // 活动处理逻辑,具体业务逻辑由子类实现
    public abstract void handleActivity();
}

分销活动处理类,执行分销活动的具体逻辑:

public class DistributionActivity extends AbstractActivity {
    @Override
    public void handleActivity() {
        System.out.println("分销活动实现逻辑");
    }
}

拼团活动处理类,执行拼团活动的具体逻辑:

public class PinTuanActivity extends AbstractActivity {
    @Override
    public void handleActivity() {
        System.out.println("拼团活动实现逻辑");
    }
}


想要根据不同的活动类型获取不同的活动处理类,而每次获取的时候不想重复创建对象,可以使用工厂模式实现。

为便于管理,将活动类型组装成枚举形式:

public enum  ActivityEnum {
    DISTRIBUTION(11,"分销活动"),
    PIN_TUAN(12,"分销活动");
    // 活动类型
    private Integer activityType;
    // 活动类型描述
    private String desc;
    /**
     * @Author: txm
     * @MethodMame: getActivityEnum
     * @Param: [activityType]
     * @Return: com.kawa.h5.api.pay.notify.ActivityEnum
     * @Description: 根据活动类型获取活动枚举
     * @Date: 2022\10\26 0026 0:22
     **/
    public static ActivityEnum getActivityEnum(Integer activityType){
        for (ActivityEnum activityEnum : ActivityEnum.values()) {
            if(activityType == activityEnum.getActivityType()){
                return activityEnum;
            }
        }
        return null;
    }
    ActivityEnum(Integer activityType, String desc) {
        this.activityType = activityType;
        this.desc = desc;
    }
    public Integer getActivityType() {
        return activityType;
    }
    public void setActivityType(Integer activityType) {
        this.activityType = activityType;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
}

活动工厂:

public class ActivityFactory {
    // 活动工厂
    private static ActivityFactory activityFactory=new ActivityFactory();
    // 活动集合,key为活动枚举信息,value为活动实现类
    private static Map<ActivityEnum,AbstractActivity> activityMap=new HashMap<ActivityEnum,AbstractActivity>();
// 初始化活动对象
static{
        activityMap.put(ActivityEnum.DISTRIBUTION,new DistributionActivity());
        activityMap.put(ActivityEnum.PIN_TUAN,new DistributionActivity());
    /**
     * @Author: txm
     * @MethodMame: getInstance
     * @Param: []
     * @Return: com.kawa.h5.api.pay.notify.ActivityFactory
     * @Description: 获取工厂实例
     * @Date: 2022\10\25 0025 23:41
     **/
    public static ActivityFactory getInstance(){
        return activityFactory;
    }
    /**
     * @Author: txm
     * @MethodMame: getActivity
     * @Param: [activityEnum]
     * @Return: void
     * @Description: 获取活动子类
     * @Date: 2022\10\26 0026 0:13
     **/
    public  AbstractActivity getActivity(ActivityEnum activityEnum){
        // 获取抽象活动的实现类对应的枚举以及活动实现类
        AbstractActivity abstractActivity = activityMap.get(activityEnum);
        return abstractActivity;
    }

优化后根据活动类型执行活动处理逻辑:

// 利用活动工厂根据活动类型获取分销活动业务处理类
AbstractActivity abstractActivity = ActivityFactory.getInstance().getActivity(ActivityEnum.getActivityEnum(11));
// 执行活动处理逻辑
abstractActivity.handleActivity();
// 输出:分销活动实现逻辑


    上面就是使用工厂模式+策略模式代替if else,只需要传递具体的活动类型即可,是不是比最初的实现方式更加简介。当然这种实现也有问题:上面的工厂类中进行活动处理类初始化时使用new对象的方式,思考是否可以利用spring核心之一的IOC方式代替new的方式创建对象,答案是可以的,看优化2.


优化2:spring容器启动完成业务对象的初始化

    容器启动过程中,将各种活动处理类加载到容器中,并与活动类型建立映射关系。可以使用注解进行关联,并根据注解获取对应的活动业务实现类。容器加载过程中完成`activityMap`的组装。涉及的spring知识点:

// 根据注解类型获取带有注解的bean信息
 Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(注解.class);

spring容器初始化操作方式之一:ApplicationListener中onApplicationEvent方法。

自定义活动注解,添加到活动处理类上完成关系绑定映射。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface ActivityAnnotation {
    ActivityEnum value();
}

分销活动处理类,添加自定义注解以及@Componet交由容器管理


@Component
@ActivityAnnotation(ActivityEnum.DISTRIBUTION)
public class DistributionActivity extends AbstractActivity {
    /**
     * @Author: txm
     * @MethodMame: handleActivity
     * @Param: []
     * @Return: void
     * @Description: 分销活动实现逻辑
     * @Date: 2022\10\25 0025 23:57
     **/
    @Override
    public void handleActivity() {
        System.out.println("分销活动实现逻辑");
    }
}

拼团活动处理类添加自定义注解以及@Componet交由容器管理

@Component
@ActivityAnnotation(ActivityEnum.PIN_TUAN)
public class PinTuanActivity extends AbstractActivity {
    /**
     * @Author: txm
     * @MethodMame: handleActivity
     * @Param: []
     * @Return: void
     * @Description: 拼团活动实现逻辑
     * @Date: 2022\10\25 0025 23:59
     **/
    @Override
    public void handleActivity() {
        System.out.println("拼团活动实现逻辑");
    }
}

活动工厂中添加组装activityMap的逻辑

public class ActivityFactory {
    // 活动工厂
    private static ActivityFactory activityFactory=new ActivityFactory();
    // 活动集合,key为活动枚举信息,value为活动实现类
    private static Map<ActivityEnum,AbstractActivity> activityMap=new HashMap<ActivityEnum,AbstractActivity>();
    /**
     * @Author: txm
     * @MethodMame: getInstance
     * @Param: []
     * @Return: com.kawa.h5.api.pay.notify.ActivityFactory
     * @Description: 获取工厂实例
     * @Date: 2022\10\25 0025 23:41
     **/
    public static ActivityFactory getInstance(){
        return activityFactory;
    }
    /**
     * @Author: txm
     * @MethodMame: addActivityMap
     * @Param: []
     * @Return: void
     * @Description: 活动集合中添加活动信息
     * @Date: 2022\10\25 0025 23:53
     **/
    public void buildActivityMap(ApplicationContext applicationContext){
        // 获取抽象活动的实现类对应的枚举以及活动实现类,即获取带有ActivityAnnotation注解的对象信息
        Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(ActivityAnnotation.class);
        for (Map.Entry<String, Object> stringObjectEntry : beansWithAnnotation.entrySet()) {
            Class<?> targetClass = AopProxyUtils.ultimateTargetClass(stringObjectEntry.getValue());
            ActivityAnnotation activityAnnotation = targetClass.getAnnotation(ActivityAnnotation.class);
            activityMap.put(activityAnnotation.value(),applicationContext.getBean(stringObjectEntry.getKey(),AbstractActivity.class));
        }
    }
    /**
     * @Author: txm
     * @MethodMame: getActivity
     * @Param: [activityEnum]
     * @Return: void
     * @Description: 获取活动子类
     * @Date: 2022\10\26 0026 0:13
     **/
    public  AbstractActivity getActivity(ActivityEnum activityEnum){
        // 获取抽象活动的实现类对应的枚举以及活动实现类
        AbstractActivity abstractActivity = activityMap.get(activityEnum);
        return abstractActivity;
    }
}

自定义监听器用于容器加载完成初始化activityMap

@Component
public class PersonalContextRefreshedListener implements ApplicationListener<ContextRefreshedEvent> {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        ApplicationContext applicationContext = event.getApplicationContext();
        ActivityFactory.getInstance().buildActivityMap(applicationContext);
}
}


   测试:根据活动类型执行对应的业务处理

// 利用活动工厂根据活动类型获取分销活动业务处理类
AbstractActivity abstractActivity = ActivityFactory.getInstance().getActivity(ActivityEnum.getActivityEnum(11));
// 执行活动处理逻辑
abstractActivity.handleActivity();
// 输出:分销活动实现逻辑


   以上是关于if else代码优化的实战记录,如果感觉有收获欢迎点赞,如果有更好的方式欢迎评论区留言!


相关文章
|
6月前
|
设计模式 编解码 C++
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用(一)
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用
198 0
|
6月前
|
设计模式 存储 缓存
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用(二)
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用
110 0
|
6月前
|
运维 Kubernetes 测试技术
容器技术:优化软件测试流程的利器
本文介绍了容器技术的概念、优势和历史发展,对比了容器与虚拟机的区别,并提及了Docker和Kubernetes等常见容器技术。容器作为轻量级虚拟化工具,提供高效、灵活的应用部署方式,广泛应用于软件开发、云计算和微服务架构。随着技术演进,容器将在边缘计算、人工智能等领域发挥更大作用,推动行业变革。
|
2月前
|
设计模式 算法 数据库连接
PHP中的设计模式:如何优化你的代码结构
在本文中,我们将深入探讨PHP中的设计模式。设计模式是解决常见软件设计问题的最佳实践。它们不是具体的代码,而是一种编程经验的总结。掌握设计模式可以帮助你写出更高效、灵活和可维护的代码。本文将介绍几种常见的设计模式,并通过示例展示如何在PHP项目中应用这些模式。无论你是PHP初学者还是有经验的开发者,都能从本文中获得启发和实用的技巧。
|
3月前
|
运维 Kubernetes 开发者
使用容器化技术优化你的应用:从理论到实践
【8月更文挑战第7天】容器化技术通过提供一致的运行环境、高效的部署与扩展能力以及资源优化,为现代应用的开发和运维带来了显著的便利。通过本文的介绍,你应该对如何使用Docker来优化你的应用有了初步的了解。从编写Dockerfile到构建镜像,再到运行容器和使用Docker Compose管理多容器应用,每一步都是向更高效、更可靠的应用交付迈进的坚实步伐。
|
3月前
|
存储 缓存 监控
在Linux中,如何优化虚拟机和容器的性能和资源使用?
在Linux中,如何优化虚拟机和容器的性能和资源使用?
|
3月前
|
Dragonfly Docker 容器
实时数仓Hologres容器镜像问题之优化私有化部署如何解决
容器镜像常遇问题包括:将过多组件打包至单一容器、使用systemd导致状态不一致、私有部署中传输未优化的镜像包及基础镜像频繁下发致网络拥堵。应采用轻量化基础镜像,明确镜像版本,并利用镜像层复用来优化。[了解更多](https://developer.aliyun.com/ask/666077)。 避免容器臃肿的方法是选用精简基础镜像,固定镜像版本,并通过镜像层复用来减少重复内容,实现高效部署。[查看详情](https://developer.aliyun.com/ask/666078)。
48 0
|
3月前
|
设计模式 缓存 Java
深入Spring Boot启动过程:揭秘设计模式与代码优化秘籍
深入Spring Boot启动过程:揭秘设计模式与代码优化秘籍
|
3月前
|
数据采集 监控 Kubernetes
Job类日志采集问题之iLogtail以减小容器发现和开始采集的延时如何优化
Job类日志采集问题之iLogtail以减小容器发现和开始采集的延时如何优化
|
5月前
|
设计模式 算法 数据库
现代软件开发中的设计模式与效率优化
在当今快节奏的软件开发环境中,设计模式不仅仅是代码组织的工具,更是提升开发效率和代码质量的重要利器。本文探讨了几种常用的设计模式在实际项目中的应用与优化策略,旨在帮助开发者在面对复杂系统和变化需求时,能够更加高效地进行软件开发。
55 1
下一篇
无影云桌面