• 用策略模式干掉代码里大量的if-eles或则Swatch,提升B格由面向过程转为面向对象


    现象 大量的分支选择型代码段看着让人头疼

      for (Field field : declaredFields) {
                Class type = field.getType();
                String key = field.getName();
                Element result = resultMap.addElement("result");
                result.addAttribute("column", StringChangeUtils.CamelhumpToUnderline(key).toLowerCase());
                result.addAttribute("property", key);
                switch (type.getSimpleName()) {
                    case "String":
                        result.addAttribute("jdbcType", "VARCHAR");
                        break;
                    case "Integer":
                        result.addAttribute("jdbcType", "NUMERIC");
                        break;
                    case "Double":
                        result.addAttribute("jdbcType", "NUMERIC");
                        break;
                    case "Date":
                        result.addAttribute("jdbcType", "DATE");
                        break;
                    default:
                        result.addAttribute("jdbcType", "VARCHAR");
                        break;
                }
    
            }
    

    如何重构成为策略模式,由硬编码的面向过程编程走向面对对象呢

    其实很简单 if里面的多个魔法常量 和HashMap里面的key是不是可以等比互换呢!!
    所以我们核心就是从一个类似于HashMap这种的容器里去获取某一个key,就等同于进去到了if 的对应分支
    而if 的对应分支 里面的业务,交给HashMap的Value去调方法完成没毛病把

    第一步抽象化这个if分支的逻辑 ---- 分析

    --比如上述代码是判断字段类型 --->通用对象接口是对象类型的·抽象·
    -- 那么这个对象具有什么能力,就是对应原始if分支的逻辑处理 呗,,
    -- 我这里是根据不同的字段类型往一个Element元素对象中填充属性。 -----所以抽出行为为往Element元素对象中填充属性

    第二步抽象化这个if分支的逻辑----- 实现

    public interface FileTypeInterfaceStrategy {
    
        void addAttribute(Element element);
    }
    
    

    第三步抽象if分支的种类,不同种类有不同实现,-----分析

    1. 比如 类型抽象 有String  类型 
    2. 比如 类型抽象 有Double  类型 
    3. 比如 类型抽象 有DATE  类型 
    4. 等等。。。。。
    

    第四步抽象if分支的种类,不同种类有不同实现,-----实现

    1. 比如 类型抽象 有String 类型 实现
    public class StringStrategy implements FileTypeInterfaceStrategy {
        @Override
        public void addAttribute(Element element) {
            element.addAttribute("jdbcType", "VARCHAR");
        }
    }
    
    
    1. 比如 类型抽象 有Integer 类型 实现
    public class IntegerStrategy implements FileTypeInterfaceStrategy {
        @Override
        public void addAttribute(Element element) {
            element.addAttribute("jdbcType", "NUMERIC");
        }
    }
    
    1. 比如 类型抽象 有Double 类型 实现
    public class DoubleStrategy implements FileTypeInterfaceStrategy {
        @Override
        public void addAttribute(Element element) {
            element.addAttribute("jdbcType", "NUMERIC");
        }
    }
    
    1. 比如 类型抽象 有Date 类型 实现
    public class DateStrategy implements FileTypeInterfaceStrategy {
        @Override
        public void addAttribute(Element element) {
            element.addAttribute("jdbcType", "DATE");
        }
    }
    
    1. 比如 类型抽象 有其他 类型 实现
    public class DefaultStrategy implements FileTypeInterfaceStrategy {
        @Override
        public void addAttribute(Element element) {
            element.addAttribute("jdbcType", "VARCHAR");
        }
    }
    

    第五步if分支的过程编程已经抽离为对象行为编程----目前如何嵌入业务分析

     思考  if选择分支,第一件事是不是拿到一个值去判断属于某一个魔法常量呢!
     其实 抽离成对象之后业同理需要知道,这里的上文行为需要下文的那一个对象的实现去处理。。
     比如,上文中拿到String、类型,我需要使用String类型的实现类去调业务方法。
     比如,上文中拿到Integer、类型,我需要使用Integer类型的实现类去调业务方法。
    

    if的分支属性和业务行为被抽离成对象--但是还有个东西没有抽离,就是IF本身的分支选择结构没抽出来 对不对
    这时候联想到第一句话:if本身业务结构还需要抽离-----它本身和HashMaP这种结构类似 是不是可以用它完成替换

    第六步if分支的过程编程已经抽离为对象行为编程----目前如何嵌入业务实现

    使用工厂方法代理策略的选择执行:其实很简单,就是new 一个HashMap,然后把所有的策略对象和Key放入HashMap,使用时候去容器里面取出来执行业务方法就完事

    public class FileTypeStrategyFactory {
    
        private FileTypeStrategyFactory() {
    
        }
    
        private static final FileTypeStrategyFactory bean = new FileTypeStrategyFactory();
    
        public static FileTypeStrategyFactory getBean() {
            return bean;
        }
    
        /**
         * 声明存储容器
         */
        private static Map factoryMap;
    
        static {
            factoryMap = new HashMap<>();
            factoryMap.put("String", new StringStrategy());
            factoryMap.put("Integer", new IntegerStrategy());
            factoryMap.put("Double", new DoubleStrategy());
            factoryMap.put("Date", new DateStrategy());
            factoryMap.put("default", new DefaultStrategy());
        }
    
    
        public FileTypeInterfaceStrategy getStrategy(String classType) {
            return factoryMap.get(classType) != null ? factoryMap.get(classType) : factoryMap.get("default");
        }
    }
    
    

    替换原始代码;

            Element resultMap = document.addElement("resultMap");
            // 添加根节点属性
            resultMap.addAttribute("id", aClass.getSimpleName() + "Map");
            resultMap.addAttribute("type", classForName);
            resultMap.addAttribute("extends", "BaseResultMap");
            for (Field field : declaredFields) {
                Class type = field.getType();
                String key = field.getName();
                Element result = resultMap.addElement("result");
                result.addAttribute("column", StringChangeUtils.CamelhumpToUnderline(key).toLowerCase());
                result.addAttribute("property", key);
                FileTypeStrategyFactory factory = FileTypeStrategyFactory.getBean();
                FileTypeInterfaceStrategy strategy = factory.getStrategy(type.getSimpleName());
                strategy.addAttribute(result);
            }
    

    策略模式+工厂方法 ----->无缝替换if-else-switch:面向过程---到面向对象是思维的转变 完结!!!!

  • 相关阅读:
    Docker: 小白之路九(从0搭建自己的Docker环境centos7)
    mysql实战之使用软链接迁移数据目录
    ArcGIS_将多个点数据整合成一个点数据
    TD Target Algorithms
    【小5聊】纯javascript实现图片放大镜效果
    抽奖小程序源码:多功能萝卜抽奖系统微信小程序抽奖功能源码【更新】
    Redis开发与运维pdf
    并查集——最小生成树算法Kruskal
    m无线通信的调制解调过程的matlab仿真,包括ASK,FSK,PSK
    C++零基础教程(函数重载)
  • 原文地址:https://www.cnblogs.com/gtnotgod/p/17736200.html