[Android]《Android 源碼設(shè)計(jì)模式解析與實(shí)戰(zhàn)》讀書筆記 1

簡(jiǎn)介

這周入手了《Android源碼設(shè)計(jì)模式解析與實(shí)戰(zhàn)》朗兵,將花一段時(shí)間去閱讀并做上讀書筆記述寡。本書的第一章介紹了面向?qū)ο蟮牧笤瓌t柿隙,這篇文章先介紹前兩條:?jiǎn)我宦氊?zé)原則和開閉原則,并觀察書中所舉的例子鲫凶,一個(gè)寫的不錯(cuò)的圖片加載器禀崖,來看看作者是怎么用代碼詮釋著兩大原則的。

單一職責(zé)原則(SRP)

單一職責(zé)所表達(dá)出的用意就是 "單一" 二字螟炫。如何劃分一個(gè)類波附、一個(gè)函數(shù)的職責(zé),每個(gè)人都有自己的看法昼钻,這需要根據(jù)個(gè)人經(jīng)驗(yàn)叶雹、具體的業(yè)務(wù)邏輯而定。但是换吧,它也有一些基本的指導(dǎo)原則,例如钥星,兩個(gè)完全不一樣的功能就不應(yīng)該放在一個(gè)類中沾瓦。一個(gè)類中應(yīng)該是一組相關(guān)性很高的函數(shù)、數(shù)據(jù)的封裝谦炒。

試想一下贯莺,如果所有的功能寫在一個(gè)類里,那么這個(gè)類會(huì)越來越大宁改,越來越復(fù)雜缕探,越不易修改維護(hù)。那么根據(jù)功能还蹲,各自獨(dú)立拆分出來爹耗,豈不是邏輯會(huì)清晰些。比如作者給的例子是一個(gè) ImageLoder 類谜喊,和一個(gè) ImageCache 類潭兽。

public class ImageCache{
    //只負(fù)責(zé)圖片緩存邏輯
}

public class ImageLoader {
    //只負(fù)責(zé)圖片的加載邏輯
}

開閉原則 (OCP)#

軟件中的對(duì)象(類、模塊斗遏、函數(shù)等)應(yīng)該對(duì)于擴(kuò)展是開放的山卦,但是對(duì)于修改是封閉的。當(dāng)軟件需要變化時(shí)诵次,我們應(yīng)該盡量通過擴(kuò)展的方式實(shí)現(xiàn)變化账蓉,而不是通過修改原有的代碼來實(shí)現(xiàn)枚碗。因?yàn)橹苯拥男薷模赡軙?huì)影響已有的正常代碼铸本。不利于出現(xiàn)錯(cuò)誤時(shí)排除問題肮雨。當(dāng)然實(shí)際開發(fā)中,修改原有代碼與擴(kuò)展代碼是同時(shí)存在的归敬。但應(yīng)盡量以擴(kuò)展為主酷含。

為了使程序更利于擴(kuò)展,作者將之前的 ImageCache改造成了一個(gè)接口

/**
 * 圖片緩存接口
 */
public interface ImageCache {
  public Bitmap get(String url);

  public void put(String url, Bitmap bmp);
}

定義了這樣一個(gè)接口后汪茧,無論是想用內(nèi)存緩存椅亚、SD卡緩存還是雙緩存都只需要實(shí)現(xiàn)該接口即可。我們看看這幾個(gè)緩存的實(shí)現(xiàn):

/**
 * 內(nèi)存緩存MemoryCache類
 */
public class MemoryCache implements ImageCache {

  private LruCache<String, Bitmap> mMemeryCache;

  public MemoryCache() {
    initLruCache();
  }

  //初始化LRU緩存
  private void initLruCache() {
    //計(jì)算可使用的最大內(nèi)存
    final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

    //取出1/4的內(nèi)存作為緩存
    final int cacheSize = maxMemory / 4;

    mMemeryCache = new LruCache<String, Bitmap>(cacheSize) {
      @Override protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight() / 1024;
      }
    };
  }

  @Override public Bitmap get(String url) {
    return mMemeryCache.get(url);
  }

  @Override public void put(String url, Bitmap bmp) {
    mMemeryCache.put(url, bmp);
  }
}

/**
 * 將圖片緩存到SD卡中
 */
public class DiskCache implements ImageCache {

  static String cacheDir = "sdcard/cache/";

  //從緩存中獲取圖片
  public Bitmap get(String url) {
    return BitmapFactory.decodeFile(cacheDir + url);
  }

  //將圖片存到內(nèi)存中
  public void put(String url, Bitmap bmp) {
    FileOutputStream fileOutputStream = null;

    try {
      fileOutputStream = new FileOutputStream(cacheDir + url);

      //30 是壓縮率舱污,表示壓縮70%; 如果不壓縮是100呀舔,表示壓縮率為0
      bmp.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } finally {
      if (fileOutputStream != null) {
        try {
          fileOutputStream.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
}

/**
 * 雙緩存
 */
public class DoubleCache implements ImageCache {
  ImageCache mMemoryCache = new MemoryCache();
  DiskCache mDiskCache = new DiskCache();

  //先從內(nèi)存緩存中獲取圖片,如果沒有就從SD卡中獲取
  public Bitmap get(String url) {
    Bitmap bitmap = mMemoryCache.get(url);
    if (bitmap == null) {
      bitmap = mDiskCache.get(url);
    }
    return bitmap;
  }

  public void put(String url, Bitmap bmp) {
    mMemoryCache.put(url, bmp);
    mDiskCache.put(url, bmp);
  }
}

在 ImageLoder 中只需要做如下一個(gè)小小的改動(dòng)

 public void setmImageCache(ImageCache cache) {
    mImageCache = cache;
  }

用戶可以通過 setmImageCache(ImageCache cache) 方法注入不同的緩存實(shí)現(xiàn)扩灯,這樣不僅能夠使 ImageLoder 更簡(jiǎn)單媚赖、健壯,也使得 ImageLoder 的可擴(kuò)展性珠插、靈活性更高惧磺。三個(gè)緩存圖片的具體實(shí)現(xiàn)完全不同,但他們都實(shí)現(xiàn)了 ImageCache 接口捻撑,就都可以通過 setmImageCache 方法注入到 ImageLoder 中磨隘,這樣 ImageLoder 就實(shí)現(xiàn)了千變?nèi)f化的緩存策略。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末顾患,一起剝皮案震驚了整個(gè)濱河市番捂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌江解,老刑警劉巖设预,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異犁河,居然都是意外死亡鳖枕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門桨螺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來耕魄,“玉大人,你說我怎么就攤上這事彭谁∥” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)则奥。 經(jīng)常有香客問我考润,道長(zhǎng),這世上最難降的妖魔是什么读处? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任糊治,我火速辦了婚禮,結(jié)果婚禮上罚舱,老公的妹妹穿的比我還像新娘井辜。我一直安慰自己,他們只是感情好管闷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布粥脚。 她就那樣靜靜地躺著,像睡著了一般包个。 火紅的嫁衣襯著肌膚如雪刷允。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天碧囊,我揣著相機(jī)與錄音树灶,去河邊找鬼。 笑死糯而,一個(gè)胖子當(dāng)著我的面吹牛天通,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播熄驼,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼像寒,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了谜洽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤吴叶,失蹤者是張志新(化名)和其女友劉穎阐虚,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚌卤,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡实束,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逊彭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咸灿。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖侮叮,靈堂內(nèi)的尸體忽然破棺而出避矢,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布审胸,位于F島的核電站亥宿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏砂沛。R本人自食惡果不足惜烫扼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望碍庵。 院中可真熱鬧映企,春花似錦、人聲如沸静浴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)马绝。三九已至豆赏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間富稻,已是汗流浹背掷邦。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留椭赋,地道東北人抚岗。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像哪怔,于是被迫代替她去往敵國(guó)和親宣蔚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

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