前言
第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