策略+工厂设计模式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【解决方案二】
对应的策略类重写InitializingBean
的afterPropertiesSet
方法将所有的实现类注册到工厂类的静态成员变量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
即可;符合开闭原则。
网友评论