基礎(chǔ)使用
工廠模式是創(chuàng)建型模式松嘶,是一種常用的獲取對象實例的方式。
1挎扰、根據(jù)名稱獲取實例
思路:根據(jù)傳入的類別名稱翠订,來分別實例化不同的實例。
/**
* 1遵倦、根據(jù)名稱獲取實例
* @param name 實例的名稱
* @return
*/
public Object getObject(String name){
if(name == null){
return null;
}
if(name.equalsIgnoreCase("Object1")){
//返回名稱對應(yīng)的實例尽超,簡化demo,這里不新建類了
return new Object();
}
if(name.equalsIgnoreCase("Object2")){
//返回名稱對應(yīng)的實例梧躺,簡化demo似谁,這里不新建類了
return new Object();
}
if(name.equalsIgnoreCase("Object3")){
//返回名稱對應(yīng)的實例,簡化demo,這里不新建類了
return new Object();
}
return null;
}
2巩踏、通過反射獲取實例
根據(jù)名稱獲取的方式十分笨拙斜筐,隨著業(yè)務(wù)的增長,工廠類會越來越重蛀缝,代碼耦合度太高顷链,下面使用類的反射機制來獲取實例。
/**
* 2屈梁、通過反射的方式嗤练,加載類
* 通過名稱實例化的方式,需要在項目組耦合大量的類在讶,且獲取實例的邏輯會越來越復(fù)雜
* 這里通過反射簡化
* @param clazz
* @return
*/
public Object getObject(Class clazz){
Object object = null;
try {
object = Class.forName(clazz.getName()).newInstance();
} catch (Exception e){
e.printStackTrace();
}
return object;
}
sl4j源碼分析(摘要)
工廠模式的經(jīng)典使用場景就是日志記錄煞抬,sl4j在獲取日志實例的時候會使用如下代碼:
private static final Logger logger = LoggerFactory.getLogger(Factory.class);
下面我們來看看LoggerFactory
是如何獲取日志實例的。
public static Logger getLogger(String name) {
ILoggerFactory iLoggerFactory = getILoggerFactory();
return iLoggerFactory.getLogger(name);
}
首先通過getILoggerFactory()
方法獲取工廠類的實例构哺,第一次調(diào)用時會進行初始化革答,無特殊配置會返回缺省的工廠實例,然后通過該工廠實例來實例化Logger
對象:
@Override
public final Logger getLogger(final String name) {
if (name == null) {
throw new IllegalArgumentException("name argument cannot be null");
}
// 如果訪問主節(jié)點直接返回
if (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name)) {
return root;
}
int i = 0;
Logger logger = root;
// 有緩存時直接返回
Logger childLogger = (Logger) loggerCache.get(name);
if (childLogger != null) {
return childLogger;
}
// 創(chuàng)建時曙强,按照層級一層一層的創(chuàng)建下去
String childName;
while (true) {
int h = LoggerNameUtil.getSeparatorIndexOf(name, i);
//當(dāng)h == -1時残拐,說明已經(jīng)拿到了類的全路徑名稱
if (h == -1) {
childName = name;
} else {
childName = name.substring(0, h);
}
// move i left of the last point
i = h + 1;
synchronized (logger) {
childLogger = logger.getChildByName(childName);
if (childLogger == null) {
childLogger = logger.createChildByName(childName);
loggerCache.put(childName, childLogger);
incSize();
}
}
logger = childLogger;
//將最后一個節(jié)點實例化后返回
if (h == -1) {
return childLogger;
}
}
}
代碼的具體邏輯已經(jīng)在注釋中標(biāo)注出來,工廠模式的根本目的是將對象的創(chuàng)建和業(yè)務(wù)場景進行解耦碟嘴,如sl4j中的LoggerFactory
可以獲取項目中任意類的日志實例溪食。