美文网首页
面向对象六大原则之单一职责原则

面向对象六大原则之单一职责原则

作者: TodoCoder | 来源:发表于2017-06-09 10:42 被阅读0次

前言

从开始接触面向对象开始就有对面向对象原则的了解,到目前为止也多次看到,可每次看到的时候,都有种似曾相识却又惊叹无比的感觉,这样的感觉明显是不对的,学完一些知识应该是融汇贯通于你的思想之中,然后穿过你的身体,穿过你的灵魂再展现出来,所以我们要躬行于知识的沃土之上,让那些让规律,想法,知识,真正能穿过我们的灵魂,我们的身体,然后再表达出来,基于此,我也想记录一下我的所学,所知!

定义

单一职责原则的英文名称是 Single Responsibility Principle,简称SRP,它的定义是:就一个类而言,应该仅有一个引起它变化的原因。也就是说,一个类中应该是一组相关性很高的函数、数据的封装。

应用

举个栗子

比如这样一个需求,写一个图片加载类,实现图片加载,并且要将图片缓存起来。

实现如下:

/**
 * 图片加载类
 */
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 imageView) {
        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);
                }
                mImageCache.put(url,bitmap);
            }
        });
    }
    private Bitmap downloadImage(String imageUrl) {
        Bitmap bitmap = null;
        try {
            URL url = new URL(imageUrl);
            final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            bitmap = BitmapFactory.decodeStream(conn.getInputStream());
            conn.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }

}

我们来分析一下这个类,功能上是没有问题的,但把缓存功能的逻辑也杂糅到图片加载类中,这明显不符合单一职责原则,更不要说扩展性、灵活性了,这样随着功能的增加,ImageLoader类只会越来越复杂。

那我们考虑一下怎么解耦?
那我们想一下,如果把图片缓存相关代码剥离出去怎么做。
我们可以把上面代码中缓存图片的LruCache对象交给一个专门的图片缓存类处理,类图如下

对应代码如下:

/**
 * 图片缓存类
 */
public class ImageCache {
    //图片LRU缓存
    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);
    }
}

/**
 * 图片加载类
 */
public class ImageLoader {
    //图片缓存
    ImageCache mImageCache = new ImageCache();
    //线程池,线程数量为CPU的数量
    ExecutorService mExecutorService = Executors.newFixedThreadPool(
            Runtime.getRuntime().availableProcessors());

    public void displayImage(final String url, final ImageView imageView) {
        Bitmap bitmap = mImageCache.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);
                }
                mImageCache.put(url,bitmap);
            }
        });
    }
    private Bitmap downloadImage(String imageUrl) {
        Bitmap bitmap = null;
        try {
            URL url = new URL(imageUrl);
            final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            bitmap = BitmapFactory.decodeStream(conn.getInputStream());
            conn.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }
}

如上述代码,把ImageLoader一拆为二,ImageLoader只负责图片加载的逻辑,ImageCache负责图片处理的逻辑,这样ImageLoader类的代码少了,职责也清晰了,当与缓存相关的需求需要改变时我们只需更改ImageCache类就可以了,当与加载图片需求需要改变时我们只需修改ImageLoader类即可,但此类的扩展灵活性也有所欠缺(此处涉及到开面向对象的另一个原则-开闭原则)

单一职责原则,主要就是单一两个字,也就是说 多个不一样的功能不应该放到一个类中,一个类应该是一组相关性很高的函数、数据的封装。

相关文章

  • Android设计模式—面向对象六大原则

    面向对象六大原则: 单一职责原则 开闭原则 里氏替换原则 依赖倒置原则 接口隔离原则 最少知识原则 单一职责原则 ...

  • 面向对象的六大原则

    面向对象的六大原则 1.单一职责原则(Single Responsibility Principle) 单一职责原...

  • 面向对象的六大原则-Android设计模式

    面向对象有六大原则:单一职责原则、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则。 单一职责原则 ...

  • 面向对象的六大原则

    面向对象的六大原则: 单一职责原则、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则。 1、单一职责...

  • 设计模式

    设计原则: 面向对象需要遵循的六大原则: 单一职责原则(SingleResponsibilityPrinciple...

  • 面向对象的六大原则

    面向对象六大原则 单一职责原则--SRP(Single Responsibility Principles)每个类...

  • 纯干货!23种设计模式大总汇

    一、面向对象的六大原则 单一职责原则——Single Responsiblity Principle 迪米特原则—...

  • 面向对象的六大原则

    设计模式基础 面向对象的六大原则 单一职责原则(Single Responsibility Principle, ...

  • JAVA设计模式

    面向对象设计的六大设计原则 1、单一职责原则(Single Responsibility Principle, S...

  • 面向对象六大原则

    设计模式的六大原则:(面向对象的六大原则) 一、单一职责原则:Single Responsibility Prin...

网友评论

      本文标题:面向对象六大原则之单一职责原则

      本文链接:https://www.haomeiwen.com/subject/ncyxqxtx.html