Filter 設計模式編碼實踐

haifeiWu發表於2018-09-21

原文地址: haifeiWu和他朋友們的部落格
部落格地址:www.hchstudio.cn
歡迎轉載,轉載請註明作者及出處,謝謝!

最近專案中遇到各種輸出資料監控,資料校驗等邏輯,一個個實現很是麻煩。專案是中途接手的,不是很熟悉,偶然一天發現專案中對 Filter 的使用擴充套件起來很是方便,所以,今天樓主來分享下,也為自己學習做個記錄。下面我們從三方面來闡述。

什麼是 Filter

Filter 在設計模式裡面被稱為責任鏈設計模式,顧名思義,我們可以在這條責任鏈上對一組資料做不同的處理。這種型別的設計模式屬於結構型模式,它結合多個標準來獲得單一標準。UML見下圖,

Filter設計模式

為什麼要使用 Filter

好處是顯而易見的,它使我們的程式碼將請求和處理分開。請求者可以不知道是誰處理的,處理者可以不用知道請求的全貌,兩者解耦,提高系統的靈活性。從而我們的程式碼更加簡潔跟易於擴充套件,而不是機械重複的Ctrl+C,Ctrl+V。當然好處還有好多,樓主就不在這裡贅述了,感興趣的小夥伴自行Google。

怎麼用 Filter 專案中的程式碼實現邏輯

定義 Filter 介面,介面中定義進行資料處理的方法。

public interface IDataHandlerFilter {

	void filter(DataPackage dataPackage);
}
複製程式碼

統一資料傳送端,將業務系統處理好的資料,統一傳送到 kafka。當然我們還可以實現 Filter 對資料進行其他處理。

public class DataSendHandlerFilter implements IDataHandlerFilter {

	public static final Logger log = LogManager.getLogger(DataSendHandlerFilter.class);

	private int logCenterType;

	//資料來源型別 0-實時資料 1-wifi資料
	private String resourceType = StringUtils.isBlank(Repository.getCityConfig().getResourceType()) ? "0" : Repository.getCityConfig().getResourceType();

	public DataSendHandlerFilter() {

		logCenterType = Repository.getSysConfig().getLogCenterType();

		//初始化kafka
		if (logCenterType == Constant.LogcenterType.KAFKA){
			KafkaProducerHelper.init(Repository.getCityConfig().getCityId(), Repository.getSysConfig());
			log.info("初始化kafka");
		}
	}

	@Override
	public void filter(DataPackage dataPackage) {

		GpsData gpsData = dataPackage.getTargetData();

		/*重複資料和時間格式錯誤資料不傳送*/
		if (null != gpsData && !gpsData.isError() && logCenterType == Constant.LogcenterType.KAFKA) {
			if (gpsData.isGps()) {
				KafkaProducerHelper.sendData(gpsData.toGpsStr(resourceType));
			}

			if (gpsData.isStn()) {
				KafkaProducerHelper.sendData(gpsData.toStnStr(resourceType));
			}
		}
	}
}

複製程式碼

設定系統要使用的 Filter ,根據具體業務有所不同。

public class HanderFilterUtil {
	
	private static List<IDataHandlerFilter> list;

	/**
	 * 這個是有先後順序的
	 * @return
	 */
	public static List<IDataHandlerFilter> getDefaultFilter(SysConfig sysConfig, CityConfig cityConfig){
		
		if (null == list){
			list = new ArrayList<>();
		}
		
		//預設提供接收日誌、重複校驗、時間格式校驗、屬性校驗、資料轉發過濾器
		list.add(new RepeatHandlerFilter());
		list.add(new DataLogHandlerFilter());
		list.add(new DataSendHandlerFilter());
		// ......
		return list;
	}
}

複製程式碼

最後我們通過呼叫 getDefaultFilter 方法來決定我們系統中使用哪幾種 Filter 來處理資料。

小結

本文中的程式碼不能直接執行,只是提供一種寫程式碼的思路,小夥伴遇到此種場景可以借鑑一下。

關注我們
關注我們

相關文章