• 代码重构:用工厂+策略模式优化过多的if else代码块


    最近在工作中优化了一段冗余的if else代码块,感觉对设计模式的理解和运用很有帮助,所以分享出来。鉴于原代码会涉及到公司的隐私,因此就不贴出来了。下面以更加通俗易懂的案例来解析。

    假如写一个针对员工上班不遵守制度做相应惩罚的程序,比如,上班迟到:罚100;上班睡觉:罚1000;上班早退:警告;上班玩游戏:严重警告;上班谈恋爱:开除等,通常都会这样写:

    public class WorkPunish {
        public static void main(String[] agrs){
            String state ="late";
            punish(state);
        }
        
        public static void punish(String state){
            if ("late".equals(state)){
                System.out.println("罚100");
            }else if ("sleep".equals(state)){
                System.out.println("罚1000");
            }else if ("early".equals(state)){
                System.out.println("警告");
            }else if ("play".equals(state)){
                System.out.println("严重警告");
            }else if ("love".equals(state)){
                System.out.println("开除");
            }
        }
    }

    可以看到,每增加一种情况都要增加一个if else判断,这样会造成这段代码非常长,可读性差、不易维护。下面就用静态工厂+策略模式来重构这段代码(对于静态工厂模式和策略模式不知道的同学请自行百度哈

    先说说思路:1、定义一个处罚的接口 ,包含一个执行处罚的方法

          2、每一种情况的处罚都抽象成一个具体处罚类并继承处罚接口(策略模式)

          3、定义一个静态工厂类,用来根据情况生产具体处罚对象,然后执行处罚的方法(静态工厂模式)。

    代码如下:

    package com.test.punish;
    
    public interface IPunish {
        void exePunish();
    }
    定义一个处罚的接口
    package com.test.punish;
    import org.springframework.beans.factory.InitializingBean;
    
    public class LatePunish implements IPunish,InitializingBean{
        public void exePunish() {
            System.out.println("罚100");
        }
        
        public void afterPropertiesSet(){
            PunishFactory.registerPunish("late", this);
        }
    
    }
    迟到处罚类
    package com.test.punish;
    import org.springframework.beans.factory.InitializingBean;
    
    public class SleepPunish implements IPunish,InitializingBean{
        public void exePunish() {
            System.out.println("罚款1000");
        }
        public void afterPropertiesSet(){
            PunishFactory.registerPunish("sleep", this);
        }
    }
    睡觉处罚类
    package com.test.punish;
    import org.springframework.beans.factory.InitializingBean;
    
    public class EarlyPunish implements IPunish,InitializingBean{
        public void exePunish() {
            System.out.println("警告");
        }
        
        public void afterPropertiesSet(){
            PunishFactory.registerPunish("early", this);
        }
    
    }
    早退处罚类

    剩下的处罚类就不贴出来了。

    package com.test.punish;
    import java.util.HashMap;
    import java.util.Map;
    
    public class PunishFactory {
        
        private static Map<String,IPunish> punishMap = new HashMap<String,IPunish>();
        
        private PunishFactory() {}
        
        private static final IPunish EMPTY = new EmptyPunish();
        
        //获取
        public static IPunish getPunish(String state) {
            IPunish result = punishMap.get(state);
            return result == null ? EMPTY : result;
        }
        
        //将处罚对象注册到这里
        public static void registerPunish(String state,IPunish o){
            punishMap.put(state, o);
        }
        
        private static class EmptyPunish implements IPunish {
            public void exePunish() {
                // Empty class
            }
        }
    }
    生产具体处罚对象的静态工厂

    重构后,处罚逻辑就可以这么写了,两行代码搞定

    public class WorkPunish {
        public static void main(String[] agrs){
            String state ="late";
            punish(state);
        }
        
        //重构后的处罚逻辑
        public static void punish(String state){
         //静态工厂类获取处罚对象 IPunish punish
    = PunishFactory.getPunish(state);
         //执行处罚逻辑 punish.exePunish(); } }

    重构后的处罚逻辑简单、清晰,后续新增一种情况,只需定义一个相应的类即可,根本不需要修改处罚逻辑,完全解耦合,这大大提高了代码的可读性和可维护性。

    不过,运用静态工厂+策略模式,也存在弊端,那就是会增加很多类;但是,当每种情况的逻辑代码很多、很复杂的时候,那么这个弊端就可以忽略不计,其优势就完全展示出来了。

  • 相关阅读:
    SQL SERVER Convert操作日期函数 分类: 数据库 2013-09-11 15:49 429人阅读 评论(0) 收藏
    UE格式化XML文件 分类: 开发常见问题解决方案 2013-08-27 15:40 6763人阅读 评论(0) 收藏
    The configuration section for Logging cannot be found in the configuration source 分类: .NET 2013-08-08 17:02 680人阅读 评论(0) 收藏
    C# 4.0 新特性dynamic、可选参数、命名参数等 分类: .NET 2013-07-26 11:15 414人阅读 评论(0) 收藏
    git 、github的简单使用
    对Http请求的总结
    Android Studio中对.9.png简单操作
    Spring简单的AOP运用
    Java 动态代理
    Spring Boot中自定义注解
  • 原文地址:https://www.cnblogs.com/pfblog/p/7815238.html
Copyright © 2020-2023  润新知