学习了何红辉、关爱民写的《Android设计模式》,对于面向对象的六大原则有进一步的理解,特此根据自己的理解记录总结一下

什么是迪米特原则

也称为最少知识原则,意思就是一个对象应该对其他对象有最少的了解,其实就是解耦合,两个类之间的关系分离的越细越好,比如面向对象的六大原则之 —— 单一原则中讲的,Imageloader类,它需要缓存,然而缓存ImageCache的具体实现,ImageLoader是不知道的。

我们打个比方,你卖肾跟iphone代理商买了一台 Iphone100 ,结果用了几天,泥马坏了,你是不是应该把手机给回代理商去保修,然而你是不需要知道,人家是怎么保修的,你只需要把手机给回代理商,让人家去保修,其他的你一概不管,保修不好就还肾,就这么简单。

实际运用一下,我们原本的ImageLoader类是直接跟内存缓存打交道的

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.LruCache;
import android.widget.ImageView;  import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;  /** * Created by Administrator on 2016/3/1. */
public class ImageLoader {  public ImageLoader() {  }  //图片缓存类  ImageCache imageCache=new ImageCache();  //线程池,线城数量为cpu的数量  ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());  /** * 显示图片 * @param url 图片的url * @param imageView 要显示的view */  public void displayImage(final String url, final ImageView imageView) {  Bitmap bitmap=imageCache.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);  }  imageCache.put(url, bitmap);  }  });  }  /** * 下載圖片 * @param imageUrl 网络图片地址 * @return 返回bitmap对象 */  public Bitmap downloadImage(String imageUrl) {  Bitmap bitmap = null;  try {  URL url = new URL(imageUrl);  HttpURLConnection conn = (HttpURLConnection) url.openConnection();  bitmap = BitmapFactory.decodeStream(conn.getInputStream());  conn.disconnect();  } catch (MalformedURLException e) {  e.printStackTrace();  } catch (IOException e) {  e.printStackTrace();  }  return bitmap;  }
}  

ImageCache类

import android.graphics.Bitmap;
import android.util.LruCache;  /** * Created by Administrator on 2016/3/1. */
public class ImageCache {  public ImageCache() {  //初始化图片缓存  initImageCache();  }  //图片缓存类  LruCache<String, Bitmap> imageCache;  /** * 初始化缓存 */  private void initImageCache() {  //计算可使用的最大内存  int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);  //只用最大内存的四分之一作为缓存大小  int cacheSize = maxMemory / 4;  imageCache = new LruCache<String, Bitmap>(cacheSize) {  @Override  protected int sizeOf(String key, Bitmap value) {  return value.getRowBytes() * value.getHeight() / 1024;  }  };  }  /** * 添加缓存 * * @param url    缓存的图片url作为缓存的key * @param bitmap 缓存的bitmap */  public void put(String url, Bitmap bitmap) {  imageCache.put(url, bitmap);  }  /** * 获取缓存的图片 * * @param url * @return */  public Bitmap get(String url) {  Bitmap bitmap = null;  bitmap = imageCache.get(url);  return bitmap;  }
}  

你会发现,我们的Imageloader在实现缓存的时候,就需要直接跟缓存类ImageCache打交道。

我们想一下,给个代理商的类

这个代理商类,我们就直接命名为ImageCache,所以,ImageCache现在的内容如下

import android.graphics.Bitmap;  /** * Created by Administrator on 2016/3/1. */
public interface ImageCache {  /** * 添加缓存 * @param url    缓存的图片url作为缓存的key * @param bitmap 缓存的bitmap */  public void put(String url, Bitmap bitmap);  /** * 获取缓存的图片 * @param url * @return */  public Bitmap get(String url);
}  

ImageCache只需要作为你的iphone手机跟厂商的桥梁,而现在的厂商是ImageLoader,它直接跟代理商ImageCache打交道

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;  import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;  /** * Created by Administrator on 2016/3/1. */
public class ImageLoader {  public ImageLoader() {  }  //默认使用内存缓存  ImageCache imageCache=new MemoryCache();  //线程池,线城数量为cpu的数量  ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());  /** * 设置要使用哪种缓存 * @param imageCache 缓存类 */  public void setImageCache(ImageCache imageCache) {  this.imageCache = imageCache;  }  /** * 显示图片 * @param url 图片的url * @param imageView 要显示的view */  public void displayImage(final String url, final ImageView imageView) {  Bitmap bitmap=imageCache.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);  }  //添加到缓存  imageCache.put(url, bitmap);  }  });  }  /** * 下載圖片 * @param imageUrl 网络图片地址 * @return 返回bitmap对象 */  public Bitmap downloadImage(String imageUrl) {  Bitmap bitmap = null;  try {  URL url = new URL(imageUrl);  HttpURLConnection conn = (HttpURLConnection) url.openConnection();  bitmap = BitmapFactory.decodeStream(conn.getInputStream());  conn.disconnect();  } catch (MalformedURLException e) {  e.printStackTrace();  } catch (IOException e) {  e.printStackTrace();  }  return bitmap;  }
}  

这个时候,我们只需要建立一个实现了ImageCache接口的实现类,也就是买了iphone100的你自己

import android.graphics.Bitmap;
import android.util.LruCache;  /** * Created by Administrator on 2016/3/1. */
public class MemoryCache implements ImageCache{  public MemoryCache() {  //初始化图片缓存  initImageCache();  }  //图片缓存类  LruCache<String, Bitmap> memoryCache;  /** * 初始化缓存 */  private void initImageCache() {  //计算可使用的最大内存  int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);  //只用最大内存的四分之一作为缓存大小  int cacheSize = maxMemory / 4;  memoryCache = new LruCache<String, Bitmap>(cacheSize) {  @Override  protected int sizeOf(String key, Bitmap value) {  return value.getRowBytes() * value.getHeight() / 1024;  }  };  }  /** * 添加缓存 * * @param url    缓存的图片url作为缓存的key * @param bitmap 缓存的bitmap */  public void put(String url, Bitmap bitmap) {  memoryCache.put(url, bitmap);  }  /** * 获取缓存的图片 * * @param url * @return */  public Bitmap get(String url) {  Bitmap bitmap = null;  bitmap = memoryCache.get(url);  return bitmap;  }
}  

这样,我们就实现了迪米特原则,一个对象应该对其他对象有最少的了解,即两个类之间没有直接关系,也就降低了耦合度,在需要添加一个卖肾买iphone的人的时候,只需要实现ImageCache接口,就能实现保修。

对于上面的解释你可能会比较迷糊,我专业点解释一下,其实就是,我们这个ImageLoader图片加载器原先在实现缓存的时候,是直接跟缓存类ImageCache打交道的,也就说明了,一但我们需要添加新的缓存方式,我们就需要更改ImageLoader里面的代码,这样明显的说明了,两个类之间是有直接关系的,而迪米特原则就是,不要有直接关系,或者说,关系越小越好,所以,我们拆开来,搞了一个中间的接口ImageCache,而真正的实现缓存的MemoryCache内存缓存类,实现了ImageCache接口,在ImageLoader中,我们只需要使用ImageCache接口就行,这样,用户在使用哪一种缓存的时候,只要实现ImageCache接口就能实现自己想要的缓存方式,而且还不需要修改ImageLoader类里面的代码,只需要通过调用ImageLoader里面的

  1. /**
  2. * 设置要使用哪种缓存
  3. * @param imageCache 缓存类
  4. */
  5. public void setImageCache(ImageCache imageCache) {
  6. this.imageCache = imageCache;
  7. }

这个方法就能通过依赖注入的方式,选择自己想要使用的缓存方式。

上一篇:《面向对象的六大原则之 —— 接口隔离原则》

面向对象的六大原则之 —— 迪米特原则相关推荐

  1. 软件设计原则之接口隔离原则、合成复用原则、迪米特原则

    系列文章目录 软件设计原则之单一职责原则.开闭原则 软件设计原则之里氏替换原则.依赖倒置原则 软件设计原则之接口隔离原则.合成复用原则.迪米特原则 文章目录 系列文章目录 一.接口隔离原则 什么是接口 ...

  2. 设计原则之迪米特原则

    迪米特原则 Law of Demeter, LOD 迪米特原则定义 迪米特原则也叫最小知识原则(The Least Knowledge Principle).即,每个模块只应该了解那些与它关系密切的模 ...

  3. 设计模式:六大原则之迪米特原则

    迪米特原则 基本介绍 定义:迪米特法则也称为最少知识原则,即一个对象应该对其他对象有最少的了解.通俗地说,一个类应该对自己需要耦合或调用的类知道的最少,被调用或耦合的类的内部是如何复杂都和我没有关系. ...

  4. 六大设计原则之迪米特原则

    迪米特原则的定义 迪米特原则(Law of Demeter,LoD),也叫最少知识原则(Low knowledge Principle,LKP): 一个对象应该对其他对象有最少的了解. 通俗的讲:一个 ...

  5. 【学习笔记】慕课网—Java设计模式精讲 第3章 软件设计七大原则-3-6 迪米特原则(最少知道原则)...

    /** * 软件设计七大原则-迪米特原则 学习笔记 * @author cnRicky * @date 2018.11.10 */ 迪米特原则(最少知道原则) 一个对象应该对其他对象保持最少的了解.又 ...

  6. 设计模式-设计原则之迪米特原则

    例子 假设老板给项目组长下达一个任务,让其去查询课程的数量 代码 public class Course {} public class TeamLeader {public void checkNu ...

  7. C# 设计原则 之 迪米特 原则

    迪米特法则又叫作最少知道原则,一般设计用于 对类内部 进行 合适的封装. 下面举例: 人关闭电脑的 示例 1.1没有实现 迪米特原则的 代码 namespace 迪米特 {internal class ...

  8. 程序设计原则之迪米特原则

    一.什么是迪米特原则 迪米特原则也叫最小知道原则,即对其他的类尽量保持最少知道.只关心自己的直接朋友类,而不关心其他的类. 直接朋友类:出现在自己的域中.方法入参中.方法出参中的类叫直接朋友类:那些在 ...

  9. 设计模式(6)之七大原则之迪米特原则

    一.定义 迪米特法则(Law of Demeter,LoD)又叫作最少知识原则(Least Knowledge Principle,LKP),产生于 1987 年美国东北大学(Northeastern ...

最新文章

  1. 必须掌握的八个DOS命令 [转]
  2. atca背板_ATCA介绍全解.ppt
  3. 别问我SolarWinds Orion API怎么用,自己进来看看,看完还不会来骂我
  4. Cloud for Customer里抓取Notification采取的是和CRM呼叫中心传统实现一样的Polling方式
  5. Mac下的Jenkins安装
  6. 新分类!全总结!最新Awesome-SLU-Survey资源库开源!
  7. 韭菜翻盘致富!加拿大学者发布比特币的价格预测模型
  8. Why is it called “armature” instead of “skeleton”? or perhaps “rig”?
  9. JS输出内容为[object Object]
  10. gdisk 创建和维护磁盘分区命令(GPT分区方案)
  11. sas最新sid及安装方法
  12. flightgear基于udp用c++传输信息
  13. 安装.NET Framework 4失败解决办法
  14. sqlite3返回码
  15. ajax到底怎么读呢
  16. 耐人寻味的Temp文件(二)
  17. intel服务器无线网卡,刷版本号?Intel再发新版无线网卡驱动
  18. 计算机控制原理 实验,计算机控制原理实验-直流电机实验
  19. 1万字精讲,这你还学不废?Python爬取腾讯视频《斛珠夫人》弹幕,并转换成词云(单线程)——爬虫实例2
  20. 菜鸟Django--更改和删除

热门文章

  1. 受伤的皇后(超详细)--蓝桥杯真题DFS
  2. Linux iscsi的磁盘扩容,Linux物理磁盘扩容流程
  3. https通信加密过程
  4. SQL复杂查询-除法实现-做题理解
  5. Java学习第八天<什么是方法><方法的定义和调用><方法的重载><命令行传参><可变参数><递归详解>
  6. 考研复试英语自我介绍
  7. 原生js html insert,原生js添加节点appendChild、insertBefore
  8. Linux下jenkins安装部署
  9. html语言中mouse over,mouseover()、mouseout()分别是什么事件?HTML中图片ONmouse事件怎样使用,例如已经有图片1?...
  10. 初入大便( debian)