面向对象的六大原则之 —— 迪米特原则
学习了何红辉、关爱民写的《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里面的
- /**
- * 设置要使用哪种缓存
- * @param imageCache 缓存类
- */
- public void setImageCache(ImageCache imageCache) {
- this.imageCache = imageCache;
- }
这个方法就能通过依赖注入的方式,选择自己想要使用的缓存方式。
上一篇:《面向对象的六大原则之 —— 接口隔离原则》
面向对象的六大原则之 —— 迪米特原则相关推荐
- 软件设计原则之接口隔离原则、合成复用原则、迪米特原则
系列文章目录 软件设计原则之单一职责原则.开闭原则 软件设计原则之里氏替换原则.依赖倒置原则 软件设计原则之接口隔离原则.合成复用原则.迪米特原则 文章目录 系列文章目录 一.接口隔离原则 什么是接口 ...
- 设计原则之迪米特原则
迪米特原则 Law of Demeter, LOD 迪米特原则定义 迪米特原则也叫最小知识原则(The Least Knowledge Principle).即,每个模块只应该了解那些与它关系密切的模 ...
- 设计模式:六大原则之迪米特原则
迪米特原则 基本介绍 定义:迪米特法则也称为最少知识原则,即一个对象应该对其他对象有最少的了解.通俗地说,一个类应该对自己需要耦合或调用的类知道的最少,被调用或耦合的类的内部是如何复杂都和我没有关系. ...
- 六大设计原则之迪米特原则
迪米特原则的定义 迪米特原则(Law of Demeter,LoD),也叫最少知识原则(Low knowledge Principle,LKP): 一个对象应该对其他对象有最少的了解. 通俗的讲:一个 ...
- 【学习笔记】慕课网—Java设计模式精讲 第3章 软件设计七大原则-3-6 迪米特原则(最少知道原则)...
/** * 软件设计七大原则-迪米特原则 学习笔记 * @author cnRicky * @date 2018.11.10 */ 迪米特原则(最少知道原则) 一个对象应该对其他对象保持最少的了解.又 ...
- 设计模式-设计原则之迪米特原则
例子 假设老板给项目组长下达一个任务,让其去查询课程的数量 代码 public class Course {} public class TeamLeader {public void checkNu ...
- C# 设计原则 之 迪米特 原则
迪米特法则又叫作最少知道原则,一般设计用于 对类内部 进行 合适的封装. 下面举例: 人关闭电脑的 示例 1.1没有实现 迪米特原则的 代码 namespace 迪米特 {internal class ...
- 程序设计原则之迪米特原则
一.什么是迪米特原则 迪米特原则也叫最小知道原则,即对其他的类尽量保持最少知道.只关心自己的直接朋友类,而不关心其他的类. 直接朋友类:出现在自己的域中.方法入参中.方法出参中的类叫直接朋友类:那些在 ...
- 设计模式(6)之七大原则之迪米特原则
一.定义 迪米特法则(Law of Demeter,LoD)又叫作最少知识原则(Least Knowledge Principle,LKP),产生于 1987 年美国东北大学(Northeastern ...
最新文章
- 必须掌握的八个DOS命令 [转]
- atca背板_ATCA介绍全解.ppt
- 别问我SolarWinds Orion API怎么用,自己进来看看,看完还不会来骂我
- Cloud for Customer里抓取Notification采取的是和CRM呼叫中心传统实现一样的Polling方式
- Mac下的Jenkins安装
- 新分类!全总结!最新Awesome-SLU-Survey资源库开源!
- 韭菜翻盘致富!加拿大学者发布比特币的价格预测模型
- Why is it called “armature” instead of “skeleton”? or perhaps “rig”?
- JS输出内容为[object Object]
- gdisk 创建和维护磁盘分区命令(GPT分区方案)
- sas最新sid及安装方法
- flightgear基于udp用c++传输信息
- 安装.NET Framework 4失败解决办法
- sqlite3返回码
- ajax到底怎么读呢
- 耐人寻味的Temp文件(二)
- intel服务器无线网卡,刷版本号?Intel再发新版无线网卡驱动
- 计算机控制原理 实验,计算机控制原理实验-直流电机实验
- 1万字精讲,这你还学不废?Python爬取腾讯视频《斛珠夫人》弹幕,并转换成词云(单线程)——爬虫实例2
- 菜鸟Django--更改和删除
热门文章
- 受伤的皇后(超详细)--蓝桥杯真题DFS
- Linux iscsi的磁盘扩容,Linux物理磁盘扩容流程
- https通信加密过程
- SQL复杂查询-除法实现-做题理解
- Java学习第八天<什么是方法><方法的定义和调用><方法的重载><命令行传参><可变参数><递归详解>
- 考研复试英语自我介绍
- 原生js html insert,原生js添加节点appendChild、insertBefore
- Linux下jenkins安装部署
- html语言中mouse over,mouseover()、mouseout()分别是什么事件?HTML中图片ONmouse事件怎样使用,例如已经有图片1?...
- 初入大便( debian)