面向?qū)ο蟮牧笤瓌t之單一職責(zé)原則

單一職責(zé)原則(SRP)又稱單一功能原則薪寓,為面向?qū)ο罅蠡驹瓌t之一社痛。

我們先來看一下官方是如何描述該原則的:

? ? ? ?該原則是由羅伯特·C·馬丁于《敏捷軟件開發(fā):原則改览、模式和實(shí)踐》一書中給出并淋。它規(guī)定一個類只應(yīng)該只有一個發(fā)生變化的原因刁憋。所謂職責(zé)是指類變化的原因,如果一個類有多于一個的動機(jī)被改變墓毒,那么這個類就具有多于一個的職責(zé)吓揪,而單一職責(zé)原則就是指一個類或者模塊應(yīng)該只有一個改變的原因。

? ? ? ?這樣解釋單一職責(zé)原則恐怕比較難以理解所计,我們可先通過實(shí)現(xiàn)一個圖片加載器柠辞,并且將圖片緩存起來的需求的例子來理解一下單一職責(zé)原則。

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.LruCache;
import android.widget.ImageView;

import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import retrofit2.http.Url;

/**
 * 圖片加載類
 */
public class ImageLoader {
    LruCache<String, Bitmap> mImageCache;
    //線程池主胧,線程數(shù)量為CPU的數(shù)量
    ExecutorService mExecutorService= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
    public ImageLoader(){
          initImageCache();
    }

    private void initImageCache()
    {
        //計(jì)算可以使用的最大內(nèi)存
        final int maxMemory= (int) (Runtime.getRuntime().maxMemory()/1024);
        //取可用內(nèi)存的1/4
        final int cachesize=maxMemory/4;
        mImageCache=new LruCache<String,Bitmap>(cachesize){
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getRowBytes()*bitmap.getHeight()/1024;
            }  
       };
    }

    /**
     * 將下載的Bitmap對象顯示在Imageview上
     * @param url
     * @param imageView
     */
    public void displayBitmap(final String url, final ImageView imageView){
        imageView.setTag(url);
        mExecutorService.submit(new Runnable() {
            @Override
            public void run() {
               Bitmap bitmap=downBitmap(url);
               if(bitmap==null)
               {
                   return;
               }
               if(imageView.getTag().equals(url))
               {
                   imageView.setImageBitmap(bitmap);
               }
                   mImageCache.put(url,bitmap);
            }
        });
    }

    /**
     * 通過URL下載圖片叭首,并返回Bitmap
     * @param imageUrl
     * @return
     */
    public Bitmap downBitmap(String imageUrl)
    {
        Bitmap bitmap=null;
        try{
            URL url=new URL(imageUrl);
            final HttpURLConnection connection= (HttpURLConnection) url.openConnection();
            bitmap= BitmapFactory.decodeStream(connection.getInputStream());
            connection.disconnect();
        }catch (Exception e)
        {
            e.printStackTrace();
        }
        return bitmap;
    }
}

? ? ? ?在這個類中我們實(shí)現(xiàn)了加載圖片习勤、設(shè)置緩存,下載圖片三個基本功能焙格。如此以來我們就實(shí)現(xiàn)了上文提出的需求图毕。然而這樣的代碼僅僅適用于我們學(xué)習(xí)使用,在真實(shí)的正產(chǎn)環(huán)境當(dāng)中由于需求會變的比較復(fù)雜眷唉,并且對可讀性吴旋,擴(kuò)展性、后期維護(hù)都會有這較高的要求厢破,如果這樣實(shí)現(xiàn)該功能荣瑟,這個類會變得越來越大,代碼也越來越復(fù)雜摩泪,圖片加載系統(tǒng)也會越來越弱笆焰。這樣寫出的功能毫無設(shè)計(jì)可言,更不要說擴(kuò)展性见坑、靈活性了嚷掠。所謂的單一職責(zé)原則,簡單的來說就是一個類負(fù)責(zé)一個功能荞驴。我們在此原則的基礎(chǔ)上對代碼進(jìn)行拆分重構(gòu)不皆。

ImageLoader類負(fù)責(zé)圖片加載功能,重構(gòu)后代碼如下:

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.LruCache;
import android.widget.ImageView;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import retrofit2.http.Url;

/**
 * 圖片加載類
 */
public class ImageLoader {
    ImageCache mImageCache=new ImageCache();
    //線程池熊楼,線程數(shù)量為CPU的數(shù)量
    ExecutorService mExecutorService= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    /**
     * 將下載的Bitmap對象顯示在Imageview上
     * @param url
     * @param imageView
     */
    public void displayBitmap(final String url, final ImageView imageView){
        imageView.setTag(url);
        mExecutorService.submit(new Runnable() {
            @Override
            public void run() {
               Bitmap bitmap=downBitmap(url);
               if(bitmap==null)
               {
                   return;
               }
               if(imageView.getTag().equals(url))
               {
                   imageView.setImageBitmap(bitmap);
               }
                   mImageCache.put(url,bitmap);
            }
        });
    }

    /**
     * 通過URL下載圖片霹娄,并返回Bitmap
     * @param imageUrl
     * @return
     */
    public Bitmap downBitmap(String imageUrl)
    {
        Bitmap bitmap=null;
        try{
            URL url=new URL(imageUrl);
            final HttpURLConnection connection= (HttpURLConnection) url.openConnection();
            bitmap= BitmapFactory.decodeStream(connection.getInputStream());
            connection.disconnect();
        }catch (Exception e)
        {
            e.printStackTrace();
        }
        return bitmap;
    }
}

ImageCache類負(fù)責(zé)圖片緩存功能代碼如下:

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.LruCache;
import android.widget.ImageView;
import java.net.URL;

/**
 * 圖片加載類
 */
public class ImageCache {
    LruCache<String, Bitmap> mImageCache;      
    public ImageCache(){
          initImageCache();
    }

    private void initImageCache()
    {
        //計(jì)算可以使用的最大內(nèi)存
        final int maxMemory= (int) (Runtime.getRuntime().maxMemory()/1024);
        //取可用內(nèi)存的1/4
        final int cachesize=maxMemory/4;
        mImageCache=new LruCache<String,Bitmap>(cachesize){
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getRowBytes()*bitmap.getHeight()/1024;
            }  
       };
    }
   /**
     * 將圖片放入緩存
     */
    public void put(String url,Bitmap bitmap)
    {
          mImageCache.put(url,bitmap);
    }
   /**
     * 將圖片從緩存中取出
     */
     public Bitmap get(String url)
    {
          return mImageCache.get(url);
      }

}

? ? ? ?我們將原來的代碼一拆為二。ImageLoader只負(fù)責(zé)圖片加載的邏輯鲫骗,新創(chuàng)建一個類ImageCache只負(fù)責(zé)處理圖片緩存的邏輯犬耻,這樣ImageLoader的代碼量減少了,職責(zé)相對也變得更清晰了执泰;當(dāng)與緩存相關(guān)的邏輯需要修改時(shí)枕磁,圖片加載的邏輯不需要改變,而圖片加載邏輯需要改變時(shí)术吝,也不會影響圖片緩存的邏輯计济。
? ? ? ?單一職責(zé)原則主要在于“單一”兩個字,如何劃分一個類排苍,或者一個函數(shù)沦寂,每個人根據(jù)自己的經(jīng)驗(yàn)和業(yè)務(wù)邏輯都有自己不同的看法。但他也有一些基本規(guī)則的纪岁,如兩個完全不一樣的功能不應(yīng)該放在同一個類中凑队。一個類中應(yīng)該是一組相關(guān)性較強(qiáng)的函數(shù)或者數(shù)據(jù)的封裝则果。我們要經(jīng)常審視自己的代碼幔翰,根據(jù)需要對類進(jìn)行相應(yīng)的拆分漩氨。單一職責(zé)原則是優(yōu)化代碼需要邁出的第一步。

參考文獻(xiàn):《Android源碼設(shè)計(jì)模式解析與實(shí)戰(zhàn)》 ----- 何紅輝 關(guān)愛民 著

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末遗增,一起剝皮案震驚了整個濱河市叫惊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌做修,老刑警劉巖霍狰,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異饰及,居然都是意外死亡蔗坯,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門燎含,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宾濒,“玉大人,你說我怎么就攤上這事屏箍』婷危” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵赴魁,是天一觀的道長卸奉。 經(jīng)常有香客問我,道長颖御,這世上最難降的妖魔是什么榄棵? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮潘拱,結(jié)果婚禮上秉继,老公的妹妹穿的比我還像新娘。我一直安慰自己泽铛,他們只是感情好尚辑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盔腔,像睡著了一般杠茬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上弛随,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天瓢喉,我揣著相機(jī)與錄音,去河邊找鬼舀透。 笑死栓票,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播走贪,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼佛猛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了坠狡?” 一聲冷哼從身側(cè)響起继找,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎逃沿,沒想到半個月后婴渡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凯亮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年边臼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片假消。...
    茶點(diǎn)故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡硼瓣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出置谦,到底是詐尸還是另有隱情堂鲤,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布媒峡,位于F島的核電站瘟栖,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏谅阿。R本人自食惡果不足惜半哟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望签餐。 院中可真熱鬧寓涨,春花似錦、人聲如沸氯檐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冠摄。三九已至糯崎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間河泳,已是汗流浹背沃呢。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拆挥,地道東北人薄霜。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親惰瓜。 傳聞我的和親對象是個殘疾皇子否副,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容