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

策略+工厂设计模式

作者: 程序员小白成长记 | 来源:发表于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