圖解mybatis日志模塊之設計模式
概述
? ? ? ? 最近經常在思考研發工程師初、中、高級工程師以及系統架構師各個級別的工程師有什么區別,隨著年齡增加我們的技術級別也在提升,但是很多人到了高級別反而更加憂慮,因為it行業35歲年齡是個坎這是行業里的共識,我覺得只要你名副其實就沒有什么焦慮的,因為任何行業高端人才肯定是成金字塔型的。要做到不焦慮我們就需要知己知彼,明確不同級別工程師的差異,而不是成為PPT工程師,到了高級工程師級別往上我們不但要具備技術的廣度還有對一些技術有深度了解,并且能夠吸收優秀軟件的設計思維形成自己的一套解決方案,成為某一方面的專家。
? ? ? ? 要形成自己的一套解決方案,我們需要擅長做軟件設計,而做好軟件設計我們需要不斷吸收優秀開源軟件的設計思想,本文將使用圖解的方式詳細分析mybatis日志模塊之設計模式的運用。
一、單例模式
????????單例模式(Singleton),保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。結構圖如下圖所示:
? ? ? ? 首先在日志模塊我們看到如下圖所示的代碼,很明顯這里應用了單例模式。
二、簡單工廠模式
????????簡單工廠模式(Simple Factory Pattern):定義一個工廠類,它可以根據參數的不同返回不同類的實例,被創建的實例通常都具有共同的父類。因為在簡單工廠模式中用于創建實例的方法是靜態(static)方法,因此簡單工廠模式又被稱為靜態工廠方法(Static Factory Method)模式,它屬于類創建型模式。結構圖如下圖所示:
? ? ? ? 在mybatis中LogFactory就是一個工廠類,會根據環境中不同日志配置來實例化日志對象,如下圖所示:
三、適配器模式
????????適配器模式(Adapter Pattern):將一個接口轉換成客戶希望的另一個接口,使接口不兼容的那些類可以一起工作,其別名為包裝器(Wrapper)。適配器模式既可以作為類結構型模式,也可以作為對象結構型模式。結構圖如下所示:
? ? ? ? mybatis為了適配各種不同日志框架的實現,設計了Log接口,從而實現了各種日志框架適配Log接口,如下圖所示:
NoLogginImpl:? ? ? ? ? ? ? ? ? ? ? ? ? ? 無日志的實現,不打印日志直接返回
Sfl4jImpl:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 適配Sfl4j的實現
Jdk14LoggingImpl:? ? ? ? ? ? ? ? ? ? ?適配使用Jdk Logging框架
JakartaCommonsLoggingImpl:? 適配使用Apache Commons Logging
Log4jImpl:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 適配Log4j
Log4j2Impl:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 適配Log4j2
StdOutImpl:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 適配直接使用System.out.println()打印日志
如下以Slf4jImpl實現為例
package org.apache.ibatis.logging.slf4j;import org.apache.ibatis.logging.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.spi.LocationAwareLogger;/*** @author Clinton Begin* @author Eduardo Macarron* @author kit* @date 20200905*/
public class Slf4jImpl implements Log {private Log log;public Slf4jImpl(String clazz) {Logger logger = LoggerFactory.getLogger(clazz);if (logger instanceof LocationAwareLogger) {try {// check for slf4j >= 1.6 method signaturelogger.getClass().getMethod("log", Marker.class, String.class, int.class, String.class, Object[].class, Throwable.class);log = new Slf4jLocationAwareLoggerImpl((LocationAwareLogger) logger);return;} catch (SecurityException | NoSuchMethodException e) {// fail-back to Slf4jLoggerImpl}}// Logger is not LocationAwareLogger or slf4j version < 1.6log = new Slf4jLoggerImpl(logger);}@Overridepublic boolean isDebugEnabled() {return log.isDebugEnabled();}@Overridepublic boolean isTraceEnabled() {return log.isTraceEnabled();}@Overridepublic void error(String s, Throwable e) {log.error(s, e);}@Overridepublic void error(String s) {log.error(s);}@Overridepublic void debug(String s) {log.debug(s);}@Overridepublic void trace(String s) {log.trace(s);}@Overridepublic void warn(String s) {log.warn(s);}}
可以看到在構造方法中實現了適配能力。
總結
? ? ? ? 閱讀優秀開源項目開源真切體會到軟件優秀的設計思想,當哪天你能看懂代碼設計的好壞,并且在自己實際工作中對設計多一些思考,那么你將不再會有焦慮,因為你的能力名副其實。