1.簡稱
單一職責(zé)原則的英文名稱是Single Responsibility Principle征峦, 簡稱RSP蜜另。
2.定義
就一個類而言,應(yīng)該僅有一個引起它變化的原因右蹦,簡單的說滔以,一個類中應(yīng)該是一組相關(guān)性很高的函數(shù)捉腥、數(shù)據(jù)的封裝。即一個類只負(fù)責(zé)一項(xiàng)職責(zé)你画,而不應(yīng)該同時負(fù)責(zé)多個職責(zé)抵碟。
3.問題
比如C類負(fù)責(zé)兩個不同的職責(zé)D1和D2。D1功能需求發(fā)生變化時坏匪,更改C類拟逮,有可能使原本正常運(yùn)行的D2發(fā)生錯誤,代碼耦合性太高,較復(fù)雜适滓。
4.解決
把功能獨(dú)立出來敦迄,讓它們滿足單一職責(zé)原則。比如創(chuàng)建兩個類C1和C2,C1完成功能D1, C2完成功能D2.任何一個功能出現(xiàn)問題都不會造成另一個功能出問題凭迹。
舉例:
public class ImageLoader {
LruCache<String,Bitmap> mImageCache;//圖片緩存
//線程池 線程數(shù)量為CPU的數(shù)量
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 bitmap) {
return bitmap.getRowBytes()* bitmap.getHeight() /1024;
}
};
}
private 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;
}
}
這個圖片加載類罚屋,將圖片的緩存即加載全部放在一個類里,耦合性太高嗅绸,隨著功能的增加脾猛,ImageLoader的代碼就會越來越多,不便于擴(kuò)展鱼鸠,靈活性查猛拴。
進(jìn)行如下拆分:
public class ImageLoader {
ImageCache mImageCache =new ImageCache();//圖片緩存
//線程池 線程數(shù)量為CPU的數(shù)量
ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private 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);
}
});
}
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 ImageCache {
LruCache<String,Bitmap> mImageCache;//圖片LRU緩存
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 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只負(fù)責(zé)圖片的加載邏輯,ImageCache只負(fù)責(zé)處理圖片的緩存蚀狰,當(dāng)與緩存相關(guān)的邏輯需要改變時漆弄,不需要修改ImageLoader類,而圖片的加載邏輯需要修改時造锅,也不會影響到緩存的邏輯。結(jié)構(gòu)變得清晰廉邑,當(dāng)擴(kuò)展性還比較欠缺哥蔚,這節(jié)我們只了解單一原則倒谷,后面再說如何使程序更靈活。
5 總結(jié):
單一原則的優(yōu)點(diǎn):
(1)減低類的復(fù)雜度糙箍,一個類只負(fù)責(zé)一項(xiàng)職責(zé)了渤愁,其業(yè)務(wù)邏輯自然就變簡單了。
(2)降低類的耦合度深夯,減少需求更改帶來的風(fēng)險
(3)提高可讀性