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

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