spring cloud脚手架项目(六)工厂类的使用以及二进制状态优化

前言

第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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章