设计模式笔记—单一职责原则
2018-01-19 22:29
381 查看
单一职责原则
概念: 英文名称是Single Responsibility Principle,简称SRP.就一个类而言,应该仅有一个引起它变化的原因。意思是当你在设计一个类的时候,应该尽量划分这个类的职责是什么,让它发生改变的因素尽量单一。举例如下:案例:接口设计
未划分之前:
public interface IUserInfo { void setUser(String userID); String getUserID(); void setPassword(String password); void setUserName(String unserName); String getUserName(); boolean changePassword(String oldPassword); boolean deleteUser(); void mapUser(); boolean addOrg(int orgID); boolean addRole(int roleID); }
可以看出这个接口涉及的很乱,因为没有将用户的属性和用户的行为划分开。应该拆分,把用户的信息抽取成一个
业务对象(Bussiness Object ),把行为抽取成一个业务逻辑类(Business Logic).
划分之后:
//负责用户的行为 public interface IUserBiz { boolean changePassword(String oldPassword); boolean deleteUser(IUserBO user); void mapUser(IUserBO user); boolean addOrg(IUserBO user,int orgID); boolean addRole(IUserBO user,int roleID); }
//负责用户的属性 public interface IUserBO { void setUser(String userID); String getUserID(); void setPassword(String password); void setUserName(String unserName); String getUserName(); }
public interface IUserInfo extends IUserBiz,IUserBO{ ...... }
调用时:
IUserBiz userInfo=new UserInfo(); //赋值时,就认为它是一个纯粹的实体类 IUserBO userBO=(IUserBO) userInfo; //执行动作时,就认为是一个业务逻辑类 IUserBiz userBiz=(IUserBiz)userInfo; userBiz.deleteUser(xx);
以上把一个接口拆分成两个接口的动作,就是依赖了单一职责原则。再看一个图片加载的案例
未划分之前:
public class ImageLoader { //图片缓存 LruCache<String,Bitmap> mImageCache; //线程的数量为CPU的数量 ExecutorService mExecutorService= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); public ImageLoader() { initImageCache(); } private void initImageCache(){ //计算可用最大内存 final int maxMemory= (int) (Runtime.getRuntime().maxMemory()/1024); final int caCheSize = maxMemory / 4; mImageCache=new LruCache<String,Bitmap>(caCheSize){ @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes()*value.getHeight()/1024; } }; } public void displayImage(final String url,final ImageView iv){ iv.setTag(url); mExecutorService.submit(new Runnable() { @Override public void run() { Bitmap bitmap=downloadImage(url); if(bitmap==null){ return; } if(iv.getTag().equals(url)){ iv.setImageBitmap(bitmap); } mImageCache.put(url,bitmap); } }); } public Bitmap downloadImage(String imageUrl){ Bitmap bitmap=null; try { URL url = new URL(imageUrl); final HttpURLConnection conn= (HttpURLConnection) url.openConnection(); bitmap= BitmapFactory.decodeStream(conn.getInputStream()); }catch (Exception e){ e.printStackTrace(); } return bitmap; } }
分析:ImageLoader耦合很严重,所有功能都写在一个类里面,这样随着功能的增加,ImageLoader类的代码量会 越来越大,代码也越来越复杂,图片加载系统就变得很脆弱,维护起来就很费力。
划分后
public class ImageLoader2 { ImageCache mImageCache=new ImageCache(); //线程的数量为CPU的数量 ExecutorService mExecutorService= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); public void displayImage(final String url,final ImageView iv){ Bitmap bitmap = mImageCache.get(url); if(bitmap!=null){ iv.setImageBitmap(bitmap); return; } iv.setTag(url); mExecutorService.submit(new Runnable() { @Override public void run() { Bitmap bitmap=downloadImage(url); if(bitmap==null){ return; } if(iv.getTag().equals(url)){ iv.setImageBitmap(bitmap); } mImageCache.put(url,bitmap); } }); } public Bitmap downloadImage(String imageUrl){ Bitmap bitmap=null; try { URL url = new URL(imageUrl); final HttpURLConnection conn= (HttpURLConnection) url.openConnection(); bitmap= BitmapFactory.decodeStream(conn.getInputStream()); }catch (Exception e){ e.printStackTrace(); } return bitmap; } }
public class ImageCache { LruCache<String,Bitmap> mImageCache; public ImageCache(){ initImageCache(); } private void initImageCache(){ //计算可用最大内存 final int maxMemory= (int) (Runtime.getRuntime().maxMemory()/1024); final int caCheSize = maxMemory / 4; mImageCache=new LruCache<String,Bitmap>(caCheSize){ @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes()*value.getHeight()/1024; } }; } public void put(String url,Bitmap bitmap){ mImageCache.put(url,bitmap); } public Bitmap get(String url){ return mImageCache.get(url); } }
分析:将ImageLoader一拆为二,ImageLoader2只负责图片加载的逻辑,而ImageCache只负责处理图片缓存的逻辑,这样ImageLoader的代码量少了,职责也清晰了。
如何来划分一个类,一个接口,一个函数的职责?每个人都有自己的看法,这个需要根据个人经验,具体的业务逻辑而定。
但是它有一些基本的指导原则,比如,两个完全不一样的功能就不应该放在一个类中。一个类中应该是一组相关性很高的函数,
数据的封装。
优点:
1) 类的复杂性降低,实现什么原则都有清晰明确的定义。
2)可读性提高,复杂性降低。
3)可维护性提高。
4)变更引起的风险降低,变更是必不可少的,如果单一职责做的好,产生的影响就会较小。
总结:本文案例占很大篇幅,主要想表明单一职责原则重点在职责的划分上,划分好职责,会给你减少很多负担。
相关文章推荐
- Java设计模式学习笔记---单一职责原则(一)
- [设计模式之禅笔记] 1. 单一职责原则
- 五 单一职责、开放—封闭、依赖倒转原则——设计模式学习笔记
- 设计模式学习笔记——单一职责原则
- 设计模式笔记(一)设计六大原则之一--单一职责原则
- pp看书笔记---设计模式之禅第二版 第一章【单一职责原则】
- 设计模式学习笔记三【单一职责原则】
- 设计模式 学习笔记(2)单一职责原则、开放封闭原则、依赖倒转原则
- 设计模式六大原则(1):单一职责原则
- 【设计模式】 单一职责原则
- [设计模式之禅读书笔记]001_设计模式六大原则(一):单一职责原则(Single Responsibility Principle)
- 设计模式六大原则(1):单一职责原则
- 设计模式实践三-单一职责原则
- java设计模式之单一职责原则(SRP)
- 设计模式六大原则(1):单一职责原则
- 设计模式六大原则(1):单一职责(SRP)
- 设计模式六大原则(1):单一职责原则
- 设计模式六大原则(1):单一职责原则
- 设计模式6大原则:单一职责原则
- 设计模式六大原则(1):单一职责原则