ToB企服应用市场:ToB评测及商务社交产业平台

标题: 用策略模式干掉代码里大量的if-eles或则Swatch,提升B格由面向过程转为面向 [打印本页]

作者: 熊熊出没    时间: 2023-10-9 07:18
标题: 用策略模式干掉代码里大量的if-eles或则Swatch,提升B格由面向过程转为面向
现象 大量的分支选择型代码段看着让人头疼
  1.   for (Field field : declaredFields) {
  2.             Class<?> type = field.getType();
  3.             String key = field.getName();
  4.             Element result = resultMap.addElement("result");
  5.             result.addAttribute("column", StringChangeUtils.CamelhumpToUnderline(key).toLowerCase());
  6.             result.addAttribute("property", key);
  7.             switch (type.getSimpleName()) {
  8.                 case "String":
  9.                     result.addAttribute("jdbcType", "VARCHAR");
  10.                     break;
  11.                 case "Integer":
  12.                     result.addAttribute("jdbcType", "NUMERIC");
  13.                     break;
  14.                 case "Double":
  15.                     result.addAttribute("jdbcType", "NUMERIC");
  16.                     break;
  17.                 case "Date":
  18.                     result.addAttribute("jdbcType", "DATE");
  19.                     break;
  20.                 default:
  21.                     result.addAttribute("jdbcType", "VARCHAR");
  22.                     break;
  23.             }
  24.         }
复制代码
如何重构成为策略模式,由硬编码的面向过程编程走向面对对象呢

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

--比如上述代码是判断字段类型 --->通用对象接口是对象类型的·抽象·
-- 那么这个对象具有什么能力,就是对应原始if分支的逻辑处理 呗,,
-- 我这里是根据不同的字段类型往一个Element元素对象中填充属性。 -----所以抽出行为为往Element元素对象中填充属性
第二步抽象化这个if分支的逻辑----- 实现
  1. public interface FileTypeInterfaceStrategy {
  2.     void addAttribute(Element element);
  3. }
复制代码
第三步抽象if分支的种类,不同种类有不同实现,-----分析
  1. 1. 比如 类型抽象 有String  类型
  2. 2. 比如 类型抽象 有Double  类型
  3. 3. 比如 类型抽象 有DATE  类型
  4. 4. 等等。。。。。
复制代码
第四步抽象if分支的种类,不同种类有不同实现,-----实现

  1. public class StringStrategy implements FileTypeInterfaceStrategy {
  2.     @Override
  3.     public void addAttribute(Element element) {
  4.         element.addAttribute("jdbcType", "VARCHAR");
  5.     }
  6. }
复制代码
  1. public class IntegerStrategy implements FileTypeInterfaceStrategy {
  2.     @Override
  3.     public void addAttribute(Element element) {
  4.         element.addAttribute("jdbcType", "NUMERIC");
  5.     }
  6. }
复制代码
  1. public class DoubleStrategy implements FileTypeInterfaceStrategy {
  2.     @Override
  3.     public void addAttribute(Element element) {
  4.         element.addAttribute("jdbcType", "NUMERIC");
  5.     }
  6. }
复制代码
  1. public class DateStrategy implements FileTypeInterfaceStrategy {
  2.     @Override
  3.     public void addAttribute(Element element) {
  4.         element.addAttribute("jdbcType", "DATE");
  5.     }
  6. }
复制代码
  1. public class DefaultStrategy implements FileTypeInterfaceStrategy {
  2.     @Override
  3.     public void addAttribute(Element element) {
  4.         element.addAttribute("jdbcType", "VARCHAR");
  5.     }
  6. }
复制代码
第五步if分支的过程编程已经抽离为对象行为编程----目前如何嵌入业务分析
  1. 思考  if选择分支,第一件事是不是拿到一个值去判断属于某一个魔法常量呢!
  2. 其实 抽离成对象之后业同理需要知道,这里的上文行为需要下文的那一个对象的实现去处理。。
  3. 比如,上文中拿到String、类型,我需要使用String类型的实现类去调业务方法。
  4. 比如,上文中拿到Integer、类型,我需要使用Integer类型的实现类去调业务方法。
复制代码
if的分支属性和业务行为被抽离成对象--但是还有个东西没有抽离,就是IF本身的分支选择结构没抽出来  对不对
这时候联想到第一句话:if本身业务结构还需要抽离-----它本身和HashMaP这种结构类似 是不是可以用它完成替换
第六步if分支的过程编程已经抽离为对象行为编程----目前如何嵌入业务实现

使用工厂方法代理策略的选择执行:其实很简单,就是new 一个HashMap,然后把所有的策略对象和Key放入HashMap,使用时候去容器里面取出来执行业务方法就完事
  1. public class FileTypeStrategyFactory {
  2.     private FileTypeStrategyFactory() {
  3.     }
  4.     private static final FileTypeStrategyFactory bean = new FileTypeStrategyFactory();
  5.     public static FileTypeStrategyFactory getBean() {
  6.         return bean;
  7.     }
  8.     /**
  9.      * 声明存储容器
  10.      */
  11.     private static Map<String, FileTypeInterfaceStrategy> factoryMap;
  12.     static {
  13.         factoryMap = new HashMap<>();
  14.         factoryMap.put("String", new StringStrategy());
  15.         factoryMap.put("Integer", new IntegerStrategy());
  16.         factoryMap.put("Double", new DoubleStrategy());
  17.         factoryMap.put("Date", new DateStrategy());
  18.         factoryMap.put("default", new DefaultStrategy());
  19.     }
  20.     public FileTypeInterfaceStrategy getStrategy(String classType) {
  21.         return factoryMap.get(classType) != null ? factoryMap.get(classType) : factoryMap.get("default");
  22.     }
  23. }
复制代码
替换原始代码;
  1.         Element resultMap = document.addElement("resultMap");
  2.         // 添加根节点属性
  3.         resultMap.addAttribute("id", aClass.getSimpleName() + "Map");
  4.         resultMap.addAttribute("type", classForName);
  5.         resultMap.addAttribute("extends", "BaseResultMap");
  6.         for (Field field : declaredFields) {
  7.             Class<?> type = field.getType();
  8.             String key = field.getName();
  9.             Element result = resultMap.addElement("result");
  10.             result.addAttribute("column", StringChangeUtils.CamelhumpToUnderline(key).toLowerCase());
  11.             result.addAttribute("property", key);
  12.             FileTypeStrategyFactory factory = FileTypeStrategyFactory.getBean();
  13.             FileTypeInterfaceStrategy strategy = factory.getStrategy(type.getSimpleName());
  14.             strategy.addAttribute(result);
  15.         }
复制代码
策略模式+工厂方法 ----->无缝替换if-else-switch:面向过程---到面向对象是思维的转变  完结!!!!

出处:http://www.cnblogs.com/gtnotgod】/----------隔壁老郭还有大号:隔壁老郭---------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4