设计模式笔记—单一职责原则

单一职责原则

            概念: 英文名称是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)变更引起的风险降低,变更是必不可少的,如果单一职责做的好,产生的影响就会较小。
总结:本文案例占很大篇幅,主要想表明单一职责原则重点在职责的划分上,划分好职责,会给你减少很多负担。




 





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值