美文网首页
策略+工厂设计模式

策略+工厂设计模式

作者: 程序员小白成长记 | 来源:发表于2021-03-01 00:03 被阅读0次

    策略+工厂设计模式demo

    一、 if/else 写法

    通过代码清单一可以看出代码里存在很多的if/else

    • 优点:
      如果if/else的数量少直接写if/else就很直观
    • 缺陷:
      1)难以阅读。如果if/else很多,比如几十个分支或者上百个分支就比较难以阅读,可能需要不断的折叠展开代码块
      2)难以维护。如果if/else很多,要添加逻辑分支的时候,需要梳理好if/else的结构,将逻辑分支添加到对应的地方
      3)难以扩展。如果if/else很多,要添加一个逻辑分支时,就需要全部回归测试,因为可能修改耦合,修改的部分会对整体有影响。
      4)代码安全。不能控制代码只部分开放。
      5)不符合代码设计思想。违反了开闭原则。

    1.1 代码清单一

    package com.example.demo.designPattern;
    
    public class UserTaskNoDesign {
        public static void main(String[] args) {
            UserTaskNoDesign userTaskNoDesign = new UserTaskNoDesign();
            userTaskNoDesign.userTaskPorcess("张三");
        }
    
        public void userTaskPorcess(String name) {
            if (name.equals("张三")) {
                System.out.println("张三完成任务1");
            } else if (name.equals("李四")) {
                System.out.println("李四完成任务1");
            } else if (name.equals("王五")) {
                System.out.println("王五完成任务1");
            } else if (name.equals("马六")) {
                System.out.println("马六完成任务1");
            }
            // ... ... 更多的else if
        }
    }
    

    二、策略模式+工厂模式

    【设计目标】
    1,代码便于扩展
    2,代码便于阅读
    3,方法便于调用

    一般将if/else逻辑中每个策略(方法)都抽离出来,可抽象成接口,使用多态在运行时决定调用哪一个实现

    2.1【解决方案一】

    1,定义一个策略接口
    2,定义每一种策略类实现改接口

    • UserTaskStrategy
    public interface UserTaskStrategy {
        void userTaskPorcess(String name);
    }
    
    • ZhangsanTaskStrategy
    public class ZhangsanTaskStrategy implements UserTaskStrategy {
    
        @Override
        public void userTaskPorcess(String name) {
            System.out.println("张三完成任务1");
        }
    }
    
    • LisiTaskStrategy
    public class LisiTaskStrategy implements UserTaskStrategy {
    
        @Override
        public void userTaskPorcess(String name) {
            System.out.println("李四完成任务1");
        }
    }
    
    • WangwuTaskStrategy
    public class WangwuTaskStrategy implements UserTaskStrategy {
    
        @Override
        public void userTaskPorcess(String name) {
            System.out.println("王五完成任务1");
        }
    }
    
    • MaliuTaskStrategy
    public class MaliuTaskStrategy implements UserTaskStrategy {
    
        @Override
        public void userTaskPorcess(String name) {
            System.out.println("马六完成任务1");
        }
    }
    

    现在if/else的逻辑都抽离了出来,但是如何根据传入的name调用对应的策略类又是一个问题

    2.2【解决方案二】

    对应的策略类重写InitializingBeanafterPropertiesSet方法将所有的实现类注册到工厂类的静态成员变量map<String,UserTaskStrategy>中,然后就可以通过工厂类的map通过name取出对应实现类。

    • UserTaskStrategy
    public interface UserTaskStrategy extends InitializingBean {
        void userTaskPorcess(String name);
    }
    
    • ZhangsanTaskStrategy
    @Component
    public class ZhangsanTaskStrategy implements UserTaskStrategy {
    
        @Override
        public void userTaskPorcess(String name) {
            System.out.println("张三完成任务1");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            UserTaskStrategyFactory.registerUserTaskStrategy("张三", this);
        }
    }
    
    • LisiTaskStrategy
    @Component
    public class LisiTaskStrategy implements UserTaskStrategy {
    
        @Override
        public void userTaskPorcess(String name) {
            System.out.println("李四完成任务1");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            UserTaskStrategyFactory.registerUserTaskStrategy("李四", this);
        }
    }
    
    • WangwuTaskStrategy
    @Component
    public class WangwuTaskStrategy implements UserTaskStrategy {
    
        @Override
        public void userTaskPorcess(String name) {
            System.out.println("王五完成任务1");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            UserTaskStrategyFactory.registerUserTaskStrategy("王五", this);
        }
    }
    
    • MaliuTaskStrategy
    @Component
    public class MaliuTaskStrategy implements UserTaskStrategy {
    
        @Override
        public void userTaskPorcess(String name) {
            System.out.println("马六完成任务1");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            UserTaskStrategyFactory.registerUserTaskStrategy("马六", this);
        }
    }
    
    • UserTaskStrategyFactory
    public class UserTaskStrategyFactory {
    
        public static Map<String, UserTaskStrategy> strategyMap = new HashMap<>();
    
        public static UserTaskStrategy getUserTaskStrategy(String name) {
            return strategyMap.get(name);
        }
    
        public static void registerUserTaskStrategy(String name, UserTaskStrategy userTaskStrategy) {
            if (StringUtils.isEmpty(name) || userTaskStrategy == null) {
                return;
            }
            strategyMap.put(name, userTaskStrategy);
        }
    }
    
    • UserTaskStrategyTest
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest
    public class UserTaskStrategyTest {
    
        @Test
        public void test() {
            String name = "张三";
            UserTaskStrategyFactory.getUserTaskStrategy(name).userTaskPorcess(name);
        }
    }
    

    这样如果有一个新的策略,只需要新建一个策略类实现UserTaskStrategy即可;符合开闭原则。

    相关文章

      网友评论

          本文标题:策略+工厂设计模式

          本文链接:https://www.haomeiwen.com/subject/ulugfltx.html