单一职责原则:
一个类中应该是一组相关性很高的函数、数据的封装。
因为单一职责的划分界限并不是总是那么清晰,很多时候都是需要靠个人经验来界定。
下面是一个不符合单一职责原则的例子:
图片缓存与加载的例子
public class ChaoticImageLoader {
// 图片缓存
LruCache<String, Bitmap> mImageCache;
// 线程池,线程数量为CPU的数量
ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
public ChaoticImageLoader() {
initImageCache();
}
private void initImageCache() {
// 计算可使用的最大内存
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// 取四分之一的可用内存作为缓存
final int cacheSize = maxMemory / 4;
mImageCache = new LruCache<String, Bitmap>(cacheSize) {
//默认返回1,这说明:默认情况下缓存的数量就是指缓存数据的总个数(每一个数据都是1).
@Override
protected int sizeOf(String key, Bitmap bitmap) {//子类覆盖这个方法来计算出自己的缓存对于每一个保存的数据所占用的量
return bitmap.getRowBytes() * bitmap.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);
}
});
}
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());
conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}在上面的例子中,耦合太过严重,不具备很好的可扩展性和灵活性。不应该把所有的功能都写在一个类里面,这样随着功能的增加,类或越来越臃肿,越来越大。
下面对上面的例子进行拆分:
/**
* 只用于处理图片显示相关的逻辑
*/
public class ImageLoader {
MemoryCache mImageCache = new MemoryCache();
ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
public void displayImage(final String url, final ImageView imageView,final Activity activity) {
Bitmap bitmap = mImageCache.get(url);//根据key从缓存中读取图片
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
return;
}
imageView.setTag(url);
mExecutorService.submit(new Runnable() {
@Override
public void run() {
final Bitmap bitmap = downloadImage(url);
if (bitmap == null) {
return;
}
if (imageView.getTag().equals(url)) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.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());
conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}
/**
* 只用于图片缓存相关的逻辑,包括将图片加入缓存和从缓存中取图片
*/
public class MemoryCache {
LruCache<String, Bitmap> mImageCache;
public MemoryCache() {
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 bitmap) {
return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
}
};
}
public void put(String url, Bitmap bitmap) {
mImageCache.put(url, bitmap);
}
public Bitmap get(String url) {
return mImageCache.get(url);
}
}拆分之后ImageLoader类只负责图片加载的逻辑,MemoryCache类只负责图片缓存的逻辑,这样ImageLoader的代码量变少了,职责也清晰了,当与缓存相关的逻辑需要修改时,不需要修改ImageLoader类,二图片加载的逻辑需要修改时也不会影响到缓存处理的逻辑。
本文通过图片缓存与加载的例子,展示了如何遵循单一职责原则来优化代码结构。通过将功能拆分为独立的类,如ImageLoader和MemoryCache,提高了代码的可维护性和扩展性。
647

被折叠的 条评论
为什么被折叠?



