此代碼為 Android 設(shè)計(jì)模式學(xué)習(xí)
涉及到的設(shè)計(jì)原則有
1 單一職責(zé)原則 比如代碼中的緩存和圖片加載功能就是分開(kāi)的
2 開(kāi)閉原則
ocp通過(guò)對(duì)IImageCache接口的實(shí)現(xiàn) 以后的緩存修改都去實(shí)現(xiàn)這個(gè)接口
保證了在不改變當(dāng)前代碼的情況下添加新的功能
接口
public interface IImageCache {
Bitmap get(String url);
void put(String url,Bitmap bitmap);
}
實(shí)現(xiàn)類
public class ImageCacheSD implements IImageCache {
public static final String cacheDir = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "temp" + File.separator; //路徑名
public ImageCacheSD() {
}
@Override
public Bitmap get(String url) {
return BitmapFactory.decodeFile(cacheDir + "/text0.jpg");
}
@Override
public void put(String url, Bitmap bitmap) {
Log.e("text123", "put: ");
FileOutputStream fileOutputStream = null;
try {
File file = new File(cacheDir);
if(!file.exists()) {
file.mkdirs();//新建目錄
}
String newPath = "text0" + ".jpg"; //文件名
File files = new File(file,newPath);
fileOutputStream = new FileOutputStream(files);
boolean compress = bitmap.compress(Bitmap.CompressFormat.PNG, 80, fileOutputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.e("text123", "put: e = " + e.toString());
} finally {
CloseUtils.CloseStream(fileOutputStream);
}
}
}
public class ImageCache implements IImageCache {
LruCache<String, Bitmap> mImageLruCache;
public ImageCache() {
initImageLoader();
}
private void initImageLoader() {
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
int cacheSize = maxMemory / 4;
mImageLruCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
return super.sizeOf(key, value);
}
};
}
@Override
public void put(String url, Bitmap bitmap) {
mImageLruCache.put(url, bitmap);
}
@Override
public Bitmap get(String url) {
return mImageLruCache.get(url);
}
}
3 里氏替換原則 lsp
一個(gè)軟件實(shí)體如果使用的是一個(gè)父類的話,那么一定適用于其子類嫂伞,而且它察覺(jué)不出父類對(duì)象和子類對(duì)象的 區(qū)別孔厉。即拯钻,子類型必須能夠替換掉它們的父類型。
子類擁有父類所有非Private的行為和屬性撰豺。
個(gè)人理解 就是子類繼承父類(可以是具體的實(shí)體類 或者抽象類) 然后在使用的時(shí)候運(yùn)用多態(tài)原理 調(diào)用的是父類的方法但是實(shí)現(xiàn)的是子類
4 依賴倒置
DIP 和LSP相比這個(gè)父類就是一個(gè)抽象接口 在使用的時(shí)候細(xì)節(jié)隱藏在這個(gè)接口的實(shí)現(xiàn)類里面 在使用的時(shí)候調(diào) 用的是接口的函數(shù)
共同點(diǎn) 都是用的是多態(tài)的原理隱藏具體的細(xì)節(jié)然子類自己實(shí)現(xiàn)自己的業(yè)務(wù)內(nèi)容 在調(diào)用的時(shí)候只是調(diào)用上級(jí)類的函數(shù)從而得到結(jié)果
區(qū)別 LSP的關(guān)鍵在于繼承(extends) 而SIP的關(guān)鍵在于實(shí)現(xiàn)(implements) LSP其實(shí)就是進(jìn)一步封裝的SIP 所以ISP相對(duì)于LSP更靈活一點(diǎn)
比如在實(shí)現(xiàn)圖片加載的時(shí)候 可以用 ImageCacheDouble 也可以用 ImageCacheSD
他們都是實(shí)現(xiàn)了IImageCache接口 所以是依賴倒置
但是如果是 ImageCacheDouble extends IImageCache 什么的就是里氏替換了
說(shuō)白了其實(shí)都是把細(xì)節(jié)隱藏還不影響擴(kuò)展性
// ImageLoader loader = new ImageLoader(new ImageCacheDouble());
ImageLoader loader = new ImageLoader(new ImageCacheSD());
String str = "https://static.firefoxchina.cn/img/201904/8_5cc650135d39b0.jpg";
loader.displayImage(str,mMainIv);
5 接口隔離原則
類間的依賴關(guān)系應(yīng)該建立在最小的接口上,接口隔離原則就是吧非常龐大的,
臃腫的接口拆分成更小的和更具體的接口 他的目標(biāo)是系統(tǒng)解耦從而容易重構(gòu)更改和重新部署
代碼中的CloseUtils這個(gè)類就是這樣的一個(gè)實(shí)現(xiàn)
其實(shí)我的理解就是用一個(gè)接口和一個(gè)實(shí)現(xiàn)類把一部分或者是一個(gè)功能獨(dú)立出出來(lái) 使用代價(jià)就是會(huì)多些一些代碼和接口
建議用在容易修改的地方或者重復(fù)多的函數(shù)中
/**
* 接口隔離原則
* fileOutputStream 實(shí)現(xiàn)了接口 Closeable
* 此接口用于負(fù)責(zé)流的關(guān)閉
*/
public class CloseUtils {
public static void CloseStream (Closeable closeable) {
if (closeable == null) {
return;
}
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用地點(diǎn)
@Override
public void put(String url, Bitmap bitmap) {
Log.e("text123", "put: ");
FileOutputStream fileOutputStream = null;
try {
File file = new File(cacheDir);
if(!file.exists()) {
file.mkdirs();//新建目錄
}
String newPath = "text0" + ".jpg"; //文件名
File files = new File(file,newPath);
fileOutputStream = new FileOutputStream(files);
boolean compress = bitmap.compress(Bitmap.CompressFormat.PNG, 80, fileOutputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.e("text123", "put: e = " + e.toString());
} finally {
CloseUtils.CloseStream(fileOutputStream);
}
}
中的
CloseUtils.CloseStream(fileOutputStream);
6 迪米特原則
其實(shí)就是中介原則 適用于 多關(guān)系的業(yè)務(wù)邏輯中 比如有兩種關(guān)系他們的直接的聯(lián)系比較復(fù)雜的時(shí)候 可以在加入一個(gè)中間類來(lái)專門(mén)處理這樣的邏輯