前言
第5,6篇分别做了全局的异常处理和aop日志。这样我们的项目的通用逻辑的处理以及基本没有问题了。本篇讲的是一个工厂类的使用
参考博客:
https://segmentfault.com/a/1190000022205403
https://blog.csdn.net/u013129944/article/details/64443054
背景
假设目前有一个需求,你需要在用户走完一串逻辑之后,对用户进行一个消息通知。方式可以是短信,微信,邮件,电话通知等等通知方式,那么应该怎么做?
很多人的回答可能就是传入参数,if else,或者稍微优雅一点,switch case
这里有一个更加好的办法,工厂设计模式。
再进一步,需求升级了。通知方式要多种多样了。比如我客户选了手机+短信,那就会同时发送2着,那要怎么做?
这里我们就会对工厂类做一个升级
代码
执行类接口
public interface TsetProcessService {
public String printName();
public String getType();
public int getNum();
}
实现方法一
@Service
@Slf4j
public class Test1Process implements TsetProcessService {
@Override
public String printName() {
log.info("test1 coming");
return "test1";
}
@Override
public String getType() {
return "test1";
}
@Override
public int getNum() {
return 1;
}
}
实现方法二
@Service
@Slf4j
public class Test2Process implements TsetProcessService {
@Override
public String printName() {
log.info("test2 coming");
return "test2";
}
@Override
public String getType() {
return "test2";
}
@Override
public int getNum() {
return 2;
}
}
工厂类
import com.chen.core.process.service.TsetProcessService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
@Slf4j
@Component
public class TestProcessFactory implements InitializingBean {
@Resource
List<TsetProcessService> serviceList = new ArrayList<>();
private static Map<String, TsetProcessService> serviceMap = new HashMap<String,TsetProcessService>();
/**
* 继承InitializingBean接口会在类注入后立刻进行操作,把具体的工厂类放入对应的map中
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
if(serviceList==null){
log.info("testProcessService null");
}
for(TsetProcessService service:serviceList){
serviceMap.put(service.getType(),service);
}
}
/**
* 通过定义的方法名获得对应的执行类
* @param type
* @return
*/
public TsetProcessService getProcessService(String type){
return serviceMap.get(type);
}
/**
* 执行多个类的方法,通过二进制状态机判断是否执行
* @param num
* @return
*/
public List<TsetProcessService> getProcessServiceByInt(int num){
List<TsetProcessService> returnList = new ArrayList<>();
for (TsetProcessService service:serviceList) {
int status = service.getNum();
//通过二进制状态进行控制
if((status&num)==status){
returnList.add(service);
}
}
return returnList;
}
}
二进制状态
例如我现在只有一个字段,但是我希望能同时放下4个状态,
分别是状态1,状态2,状态3 只有true和false2种
那么 就可以用二进制状态机整合
分别状态对应为
状态1 001
状态2 010
状态3 100
那么状态1和状态2的叠加:011
状态2和状态3的叠加110
状态1和状态3的叠加101
状态1,2,3都叠加111
如何判断是否有这个状态呢,a&b==b
true说明状态存在,false说明状态不存在
测试方法
测试工厂
public Result<String> test7(String a) {
TsetProcessService service = testProcessFactory.getProcessService(a);
String result = service.printName();
return Result.success(result);
}
传入a = test1 ,则会进行test1的方法
传入a = test2,则会进行test1的方法
测试二进制状态机
public Result<String> test8(int a) {
List<TsetProcessService> serviceList = testProcessFactory.getProcessServiceByInt(a);
for(TsetProcessService service:serviceList){
service.printName();
}
return Result.success("scuuess");
}
传入1,则只进行test1方法,
传入2,则只进行test2方法
传入3,test1和test2方法都执行
结尾
这样我们的工厂策略模式就完成了。通过工厂策略模式,我们可以很方便的解决if else问题,对于同类型的操作也会有一个很优雅的扩张。也可以减少serivce和controller中的冗余,只需要传入一个@resource注解就可以同时进行多个service操作
github地址:https://github.com/alex9567/SpringCloudScaffold
转载:https://blog.csdn.net/qq_33562996/article/details/106077818