前言
從開始接觸面向?qū)ο箝_始就有對面向?qū)ο笤瓌t的了解拇惋,到目前為止也多次看到秒啦,可每次看到的時候缆巧,都有種似曾相識卻又驚嘆無比的感覺,這樣的感覺明顯是不對的莉炉,學完一些知識應該是融匯貫通于你的思想之中钓账,然后穿過你的身體,穿過你的靈魂再展現(xiàn)出來絮宁,所以我們要躬行于知識的沃土之上梆暮,讓那些讓規(guī)律,想法绍昂,知識啦粹,真正能穿過我們的靈魂,我們的身體窘游,然后再表達出來唠椭,基于此,我也想記錄一下我的所學忍饰,所知贪嫂!
定義
單一職責原則的英文名稱是 Single Responsibility Principle,簡稱SRP,它的定義是:就一個類而言艾蓝,應該僅有一個引起它變化的原因力崇。也就是說斗塘,一個類中應該是一組相關性很高的函數(shù)、數(shù)據(jù)的封裝亮靴。
應用
舉個栗子
比如這樣一個需求馍盟,寫一個圖片加載類,實現(xiàn)圖片加載台猴,并且要將圖片緩存起來朽合。
實現(xiàn)如下:
/**
* 圖片加載類
*/
public class ImageLoader {
//圖片緩存
LruCache<String,Bitmap> mImageCache;
//線程池,線程數(shù)量為CPU的數(shù)量
ExecutorService mExecutorService = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors());
public ImageLoader(){
initImageCache();
}
private void initImageCache() {
//計算可使用的最大內(nèi)存
final int maxMemory = (int)(Runtime.getRuntime().maxMemory() / 1024);
//取四分之一的可用內(nèi)存作為緩存
final int cacheSize = maxMemory / 4;
mImageCache = new LruCache<String,Bitmap>(cacheSize){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
};
}
public void displayImage(final String url, final ImageView imageView) {
imageView.setTag(url);
mExecutorService.submit(new Runnable() {
@Override
public void run() {
Bitmap bitmap = downloadImage(url);
if (bitmap == null) {
return;
}
if (imageView.getTag().equals(url)) {
imageView.setImageBitmap(bitmap);
}
mImageCache.put(url,bitmap);
}
});
}
private Bitmap downloadImage(String imageUrl) {
Bitmap bitmap = null;
try {
URL url = new URL(imageUrl);
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
bitmap = BitmapFactory.decodeStream(conn.getInputStream());
conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}
我們來分析一下這個類饱狂,功能上是沒有問題的曹步,但把緩存功能的邏輯也雜糅到圖片加載類中,這明顯不符合單一職責原則休讳,更不要說擴展性讲婚、靈活性了,這樣隨著功能的增加俊柔,ImageLoader類只會越來越復雜筹麸。
那我們考慮一下怎么解耦?
那我們想一下,如果把圖片緩存相關代碼剝離出去怎么做雏婶。
我們可以把上面代碼中緩存圖片的LruCache對象交給一個專門的圖片緩存類處理物赶,類圖如下
對應代碼如下:
/**
* 圖片緩存類
*/
public class ImageCache {
//圖片LRU緩存
LruCache<String,Bitmap> mImageCache;
public ImageCache() {
initImageCache();
}
private void initImageCache() {
//計算可使用的最大內(nèi)存
final int maxMemory = (int)(Runtime.getRuntime().maxMemory() / 1024);
//取四分之一的可用內(nèi)存作為緩存
final int cacheSize = maxMemory / 4;
mImageCache = new LruCache<String,Bitmap>(cacheSize){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
};
}
public void put (String url,Bitmap bitmap) {
mImageCache.put(url,bitmap);
}
public Bitmap get(String url) {
return mImageCache.get(url);
}
}
/**
* 圖片加載類
*/
public class ImageLoader {
//圖片緩存
ImageCache mImageCache = new ImageCache();
//線程池,線程數(shù)量為CPU的數(shù)量
ExecutorService mExecutorService = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors());
public void displayImage(final String url, final ImageView imageView) {
Bitmap bitmap = mImageCache.get(url);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
return;
}
imageView.setTag(url);
mExecutorService.submit(new Runnable() {
@Override
public void run() {
Bitmap bitmap = downloadImage(url);
if (bitmap == null) {
return;
}
if (imageView.getTag().equals(url)) {
imageView.setImageBitmap(bitmap);
}
mImageCache.put(url,bitmap);
}
});
}
private Bitmap downloadImage(String imageUrl) {
Bitmap bitmap = null;
try {
URL url = new URL(imageUrl);
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
bitmap = BitmapFactory.decodeStream(conn.getInputStream());
conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}
如上述代碼留晚,把ImageLoader一拆為二酵紫,ImageLoader只負責圖片加載的邏輯,ImageCache負責圖片處理的邏輯错维,這樣ImageLoader類的代碼少了奖地,職責也清晰了,當與緩存相關的需求需要改變時我們只需更改ImageCache類就可以了赋焕,當與加載圖片需求需要改變時我們只需修改ImageLoader類即可参歹,但此類的擴展靈活性也有所欠缺(此處涉及到開面向?qū)ο蟮牧硪粋€原則-開閉原則)
單一職責原則,主要就是單一兩個字隆判,也就是說 多個不一樣的功能不應該放到一個類中犬庇,一個類應該是一組相關性很高的函數(shù)、數(shù)據(jù)的封裝蜜氨。