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

簡(jiǎn)介

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

單一職責(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ù)的封裝。

試想一下,如果所有的功能寫(xiě)在一個(gè)類里,那么這個(gè)類會(huì)越來(lái)越大,越來(lái)越復(fù)雜,越不易修改維護(hù)。那么根據(jù)功能,各自獨(dú)立拆分出來(lái),豈不是邏輯會(huì)清晰些。比如作者給的例子是一個(gè) ImageLoder 類,和一個(gè) ImageCache 類。

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

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

開(kāi)閉原則 (OCP)#

軟件中的對(duì)象(類、模塊、函數(shù)等)應(yīng)該對(duì)于擴(kuò)展是開(kāi)放的,但是對(duì)于修改是封閉的。當(dāng)軟件需要變化時(shí),我們應(yīng)該盡量通過(guò)擴(kuò)展的方式實(shí)現(xiàn)變化,而不是通過(guò)修改原有的代碼來(lái)實(shí)現(xiàn)。因?yàn)橹苯拥男薷?,可能?huì)影響已有的正常代碼。不利于出現(xiàn)錯(cuò)誤時(shí)排除問(wèn)題。當(dāng)然實(shí)際開(kāi)發(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è)接口后,無(wú)論是想用內(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)存緩存中獲取圖片,如果沒(mé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;
  }

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容