1.概述
講工廠模式之前我們先來講一下我們項(xiàng)目中可能存在的一個(gè)問題。大家的項(xiàng)目中使用的緩存,不管是官方提供的SharePreference還是File存儲(chǔ)、數(shù)據(jù)庫、還是基于這些封裝后的方案,在項(xiàng)目的使用中我們有時(shí)候沒有考慮到后期應(yīng)用版本升級迭代,在需要緩存數(shù)據(jù)到本地的地方我們可能這樣寫,以我目前使用的File緩存的開源方案ACache為例子:
最基本的用法,沒有任何封裝,最原始的配方
ACache aCache = ACache.get(getActivity());
aCache.put(CacheKey.SHOW_FLAG, "1");
aCache.getAsString(CacheKey.SHOW_FLAG);
開始用著還好,但是時(shí)間長了會(huì)遇到一個(gè)尷尬的情況:我們的產(chǎn)品越來越大,要求頁越來越高,存儲(chǔ)方案可能會(huì)細(xì)分出來,比如我們想替換成SharePreference的方案,數(shù)據(jù)庫方案,像上面的那種寫法,你得全局搜索然后一遍遍的改,這也太煩了,一點(diǎn)也不優(yōu)雅。軟件工程里面有個(gè)說法,如果遇到不能解決的問題,加個(gè)中間層就好了。
有沒有好的方式解決這個(gè)問題呢?這就是工廠模式。
多說一句我對設(shè)計(jì)模式的理解:其實(shí)設(shè)計(jì)模式就是大家在編碼過程中積累的一種經(jīng)驗(yàn),說到底是一個(gè)為了解決代碼問題的模版。大家在相關(guān)的場景下照著這個(gè)模版做就能寫出看起來還不錯(cuò)代碼來。
工廠模式分為三種,從復(fù)雜的度、擴(kuò)展性上分為:簡單工廠模式、工廠方法模式、抽象工廠模式。
簡單工廠模式
public class AppIOFactory implements Factory {
public static final String PREFERENCES = "1";
public static final String MEMERY = "2";
public static final String DISK = "3";
@Override
public IOHandler createIOHandler(String type) {
switch (type){
case PREFERENCES:
return new PreferenceHandler();
break;
case MEMERY:
return new MemeryHandler();
break;
case DISK:
return new DiskHandler();
break;
default:
return new PreferenceHandler();
break;
}
}
}
使用方法
AppIOFactory ioFactory = new AppIOFactory();
IOHandler ioHandler = ioFactory.createIOHandler(AppIOFactory.DISK);
ioHandler.put("name","王");
String name = ioHandler.get("name");
總結(jié)一下,我們這里不是在需要緩存的地方就new一個(gè)某種緩存模式的對象,而是通過AppIOFactory去統(tǒng)一的管理。
工廠方法模式
上面我們注意到AppIOFactory掌管了具體的緩存類的創(chuàng)建,實(shí)際使用中可能還有其它的功能,我們一般把這種類叫做“上帝類”,怎么樣可以減輕這個(gè)“上帝類”的負(fù)擔(dān)呢,這就是工廠方法模式。代碼我這里就不給出了,其實(shí)就是為每種緩存方式創(chuàng)建一個(gè)IOFactory繼承Factory,這個(gè)IOFactory只負(fù)責(zé)某個(gè)緩存類的創(chuàng)建。其它的和簡單工廠模式一樣。
工廠方法模式的使用
DiskIOFactory diskIOFactory = new DiskIOFactory();
IOHandler ioHandler = diskIOFactory.createIOHandler();
ioHandler.save("name","wang");
DiskIOFactory diskIOFactory = new DiskIOFactory();
IOHandler ioHandler = diskIOFactory.createIOHandler();
String userName = ioHandler.getString("name");
好處顯而易見,一個(gè)工廠負(fù)責(zé)一個(gè)對象的創(chuàng)建,類更輕量級了。但是問題頁隨之而來,工廠類變多了,這個(gè)時(shí)候我們的終極版本來了,就是抽象工廠模式。
抽象工廠模式
要解決簡單工廠模式和工廠方法模式造成的痛點(diǎn),其實(shí)我們結(jié)合一下他們的思想
public interface Factory {
void put(String key,String value);
String get(String key);
}
public class DiskFactory implements Factory {
@Override
public void put(String key, String value) {
}
@Override
public String get(String key) {
return null;
}
}
public interface IOFactory {
Factory createMemoryFactory();
Factory createDiskFactory();
Factory createPreferenceFactory();
}
public class AppIOFactory implements IOFactory {
@Override
public Factory createMemoryFactory() {
return new MemoryFactory();
}
@Override
public Factory createDiskFactory() {
return new DiskFactory();
}
@Override
public Factory createPreferenceFactory() {
return new PreferenceFactory();
}
}
使用
Factory factory = new AppIOFactory();
factory.createDiskFactory().put("name","wang");
String name = factory.createDiskFactory().get("name");
總結(jié):其實(shí)三種工廠方法模式的區(qū)分并沒有那么嚴(yán)格,有時(shí)候你寫著寫著就會(huì)發(fā)現(xiàn)自己本來要寫工廠方法模式然后寫的是抽象工廠模式,平時(shí)在自己的項(xiàng)目中遇到比較復(fù)雜的地方想解耦的話,先想一想有沒有什么設(shè)計(jì)模式思想可以借鑒,這樣就可以寫出優(yōu)雅的代碼了。