zoukankan      html  css  js  c++  java
  • 面向对象的六大原则之 —— 迪米特原则

    学习了何红辉、关爱民写的《Android设计模式》,对于面向对象的六大原则有进一步的理解,特此根据自己的理解记录总结一下

    什么是迪米特原则

    也称为最少知识原则,意思就是一个对象应该对其他对象有最少的了解,其实就是解耦合,两个类之间的关系分离的越细越好,比如面向对象的六大原则之 —— 单一原则中讲的,Imageloader类,它需要缓存,然而缓存ImageCache的具体实现,ImageLoader是不知道的。

    我们打个比方,你卖肾跟iphone代理商买了一台 Iphone100 ,结果用了几天,泥马坏了,你是不是应该把手机给回代理商去保修,然而你是不需要知道,人家是怎么保修的,你只需要把手机给回代理商,让人家去保修,其他的你一概不管,保修不好就还肾,就这么简单。

    实际运用一下,我们原本的ImageLoader类是直接跟内存缓存打交道的

    [java] view plain copy
    1. import android.graphics.Bitmap;    
    2. import android.graphics.BitmapFactory;    
    3. import android.util.LruCache;    
    4. import android.widget.ImageView;    
    5.     
    6. import java.io.IOException;    
    7. import java.net.HttpURLConnection;    
    8. import java.net.MalformedURLException;    
    9. import java.net.URL;    
    10. import java.util.concurrent.ExecutorService;    
    11. import java.util.concurrent.Executors;    
    12.     
    13. /**  
    14.  * Created by Administrator on 2016/3/1.  
    15.  */    
    16. public class ImageLoader {    
    17.     
    18.     public ImageLoader() {    
    19.     }    
    20.     
    21.     //图片缓存类    
    22.     ImageCache imageCache=new ImageCache();    
    23.     //线程池,线城数量为cpu的数量    
    24.     ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());    
    25.     
    26.     /**  
    27.      * 显示图片  
    28.      * @param url 图片的url  
    29.      * @param imageView 要显示的view  
    30.      */    
    31.     public void displayImage(final String url, final ImageView imageView) {    
    32.         Bitmap bitmap=imageCache.get(url);    
    33.         if(bitmap!=null){    
    34.             imageView.setImageBitmap(bitmap);    
    35.             return;    
    36.         }    
    37.         imageView.setTag(url);    
    38.         mExecutorService.submit(new Runnable() {    
    39.             @Override    
    40.             public void run() {    
    41.                 Bitmap bitmap = downloadImage(url);    
    42.                 if (bitmap == null) {    
    43.                     return;    
    44.                 }    
    45.                 if (imageView.getTag().equals(url)) {    
    46.                     imageView.setImageBitmap(bitmap);    
    47.                 }    
    48.                 imageCache.put(url, bitmap);    
    49.             }    
    50.         });    
    51.     }    
    52.     /**  
    53.      * 下載圖片  
    54.      * @param imageUrl 网络图片地址  
    55.      * @return 返回bitmap对象  
    56.      */    
    57.     public Bitmap downloadImage(String imageUrl) {    
    58.         Bitmap bitmap = null;    
    59.         try {    
    60.             URL url = new URL(imageUrl);    
    61.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();    
    62.             bitmap = BitmapFactory.decodeStream(conn.getInputStream());    
    63.             conn.disconnect();    
    64.         } catch (MalformedURLException e) {    
    65.             e.printStackTrace();    
    66.         } catch (IOException e) {    
    67.             e.printStackTrace();    
    68.         }    
    69.         return bitmap;    
    70.     }    
    71. }    


    ImageCache类

    [java] view plain copy
    1. import android.graphics.Bitmap;    
    2. import android.util.LruCache;    
    3.     
    4. /**  
    5.  * Created by Administrator on 2016/3/1.  
    6.  */    
    7. public class ImageCache {    
    8.     
    9.     public ImageCache() {    
    10.         //初始化图片缓存    
    11.         initImageCache();    
    12.     }    
    13.     
    14.     //图片缓存类    
    15.     LruCache<String, Bitmap> imageCache;    
    16.     
    17.     /**  
    18.      * 初始化缓存  
    19.      */    
    20.     private void initImageCache() {    
    21.         //计算可使用的最大内存    
    22.         int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);    
    23.         //只用最大内存的四分之一作为缓存大小    
    24.         int cacheSize = maxMemory / 4;    
    25.         imageCache = new LruCache<String, Bitmap>(cacheSize) {    
    26.             @Override    
    27.             protected int sizeOf(String key, Bitmap value) {    
    28.                 return value.getRowBytes() * value.getHeight() / 1024;    
    29.             }    
    30.         };    
    31.     }    
    32.     
    33.     /**  
    34.      * 添加缓存  
    35.      *  
    36.      * @param url    缓存的图片url作为缓存的key  
    37.      * @param bitmap 缓存的bitmap  
    38.      */    
    39.     public void put(String url, Bitmap bitmap) {    
    40.         imageCache.put(url, bitmap);    
    41.     }    
    42.     
    43.     /**  
    44.      * 获取缓存的图片  
    45.      *  
    46.      * @param url  
    47.      * @return  
    48.      */    
    49.     public Bitmap get(String url) {    
    50.         Bitmap bitmap = null;    
    51.         bitmap = imageCache.get(url);    
    52.         return bitmap;    
    53.     }    
    54. }    

    你会发现,我们的Imageloader在实现缓存的时候,就需要直接跟缓存类ImageCache打交道。

    我们想一下,给个代理商的类

    这个代理商类,我们就直接命名为ImageCache,所以,ImageCache现在的内容如下

    [java] view plain copy
    1. import android.graphics.Bitmap;    
    2.     
    3. /**  
    4.  * Created by Administrator on 2016/3/1.  
    5.  */    
    6. public interface ImageCache {    
    7.     /**  
    8.      * 添加缓存  
    9.      * @param url    缓存的图片url作为缓存的key  
    10.      * @param bitmap 缓存的bitmap  
    11.      */    
    12.     public void put(String url, Bitmap bitmap);    
    13.     
    14.     /**  
    15.      * 获取缓存的图片  
    16.      * @param url  
    17.      * @return  
    18.      */    
    19.     public Bitmap get(String url);    
    20. }    

    ImageCache只需要作为你的iphone手机跟厂商的桥梁,而现在的厂商是ImageLoader,它直接跟代理商ImageCache打交道

    [java] view plain copy
    1. import android.graphics.Bitmap;    
    2. import android.graphics.BitmapFactory;    
    3. import android.widget.ImageView;    
    4.     
    5. import java.io.IOException;    
    6. import java.net.HttpURLConnection;    
    7. import java.net.MalformedURLException;    
    8. import java.net.URL;    
    9. import java.util.concurrent.ExecutorService;    
    10. import java.util.concurrent.Executors;    
    11.     
    12. /**  
    13.  * Created by Administrator on 2016/3/1.  
    14.  */    
    15. public class ImageLoader {    
    16.     
    17.     public ImageLoader() {    
    18.     }    
    19.     
    20.     //默认使用内存缓存    
    21.     ImageCache imageCache=new MemoryCache();    
    22.     
    23.     //线程池,线城数量为cpu的数量    
    24.     ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());    
    25.     
    26.     /**  
    27.      * 设置要使用哪种缓存  
    28.      * @param imageCache 缓存类  
    29.      */    
    30.     public void setImageCache(ImageCache imageCache) {    
    31.         this.imageCache = imageCache;    
    32.     }    
    33.     
    34.     /**  
    35.      * 显示图片  
    36.      * @param url 图片的url  
    37.      * @param imageView 要显示的view  
    38.      */    
    39.     public void displayImage(final String url, final ImageView imageView) {    
    40.         Bitmap bitmap=imageCache.get(url);    
    41.     
    42.         if(bitmap!=null){    
    43.             imageView.setImageBitmap(bitmap);    
    44.             return;    
    45.         }    
    46.         imageView.setTag(url);    
    47.         mExecutorService.submit(new Runnable() {    
    48.             @Override    
    49.             public void run() {    
    50.                 Bitmap bitmap = downloadImage(url);    
    51.                 if (bitmap == null) {    
    52.                     return;    
    53.                 }    
    54.                 if (imageView.getTag().equals(url)) {    
    55.                     imageView.setImageBitmap(bitmap);    
    56.                 }    
    57.                 //添加到缓存    
    58.                 imageCache.put(url, bitmap);    
    59.             }    
    60.         });    
    61.     }    
    62.     
    63.     /**  
    64.      * 下載圖片  
    65.      * @param imageUrl 网络图片地址  
    66.      * @return 返回bitmap对象  
    67.      */    
    68.     public Bitmap downloadImage(String imageUrl) {    
    69.         Bitmap bitmap = null;    
    70.         try {    
    71.             URL url = new URL(imageUrl);    
    72.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();    
    73.             bitmap = BitmapFactory.decodeStream(conn.getInputStream());    
    74.             conn.disconnect();    
    75.         } catch (MalformedURLException e) {    
    76.             e.printStackTrace();    
    77.         } catch (IOException e) {    
    78.             e.printStackTrace();    
    79.         }    
    80.         return bitmap;    
    81.     }    
    82. }    

    这个时候,我们只需要建立一个实现了ImageCache接口的实现类,也就是买了iphone100的你自己

    [java] view plain copy
    1. import android.graphics.Bitmap;    
    2. import android.util.LruCache;    
    3.     
    4. /**  
    5.  * Created by Administrator on 2016/3/1.  
    6.  */    
    7. public class MemoryCache implements ImageCache{    
    8.     
    9.     public MemoryCache() {    
    10.         //初始化图片缓存    
    11.         initImageCache();    
    12.     }    
    13.     
    14.     //图片缓存类    
    15.     LruCache<String, Bitmap> memoryCache;    
    16.     
    17.     /**  
    18.      * 初始化缓存  
    19.      */    
    20.     private void initImageCache() {    
    21.         //计算可使用的最大内存    
    22.         int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);    
    23.         //只用最大内存的四分之一作为缓存大小    
    24.         int cacheSize = maxMemory / 4;    
    25.         memoryCache = new LruCache<String, Bitmap>(cacheSize) {    
    26.             @Override    
    27.             protected int sizeOf(String key, Bitmap value) {    
    28.                 return value.getRowBytes() * value.getHeight() / 1024;    
    29.             }    
    30.         };    
    31.     }    
    32.     
    33.     /**  
    34.      * 添加缓存  
    35.      *  
    36.      * @param url    缓存的图片url作为缓存的key  
    37.      * @param bitmap 缓存的bitmap  
    38.      */    
    39.     public void put(String url, Bitmap bitmap) {    
    40.         memoryCache.put(url, bitmap);    
    41.     }    
    42.     
    43.     /**  
    44.      * 获取缓存的图片  
    45.      *  
    46.      * @param url  
    47.      * @return  
    48.      */    
    49.     public Bitmap get(String url) {    
    50.         Bitmap bitmap = null;    
    51.         bitmap = memoryCache.get(url);    
    52.         return bitmap;    
    53.     }    
    54. }    

    这样,我们就实现了迪米特原则,一个对象应该对其他对象有最少的了解,即两个类之间没有直接关系,也就降低了耦合度,在需要添加一个卖肾买iphone的人的时候,只需要实现ImageCache接口,就能实现保修。

    对于上面的解释你可能会比较迷糊,我专业点解释一下,其实就是,我们这个ImageLoader图片加载器原先在实现缓存的时候,是直接跟缓存类ImageCache打交道的,也就说明了,一但我们需要添加新的缓存方式,我们就需要更改ImageLoader里面的代码,这样明显的说明了,两个类之间是有直接关系的,而迪米特原则就是,不要有直接关系,或者说,关系越小越好,所以,我们拆开来,搞了一个中间的接口ImageCache,而真正的实现缓存的MemoryCache内存缓存类,实现了ImageCache接口,在ImageLoader中,我们只需要使用ImageCache接口就行,这样,用户在使用哪一种缓存的时候,只要实现ImageCache接口就能实现自己想要的缓存方式,而且还不需要修改ImageLoader类里面的代码,只需要通过调用ImageLoader里面的

    1. /** 
    2.      * 设置要使用哪种缓存 
    3.      * @param imageCache 缓存类 
    4.      */  
    5.     public void setImageCache(ImageCache imageCache) {  
    6.         this.imageCache = imageCache;  
    7.     }  
    这个方法就能通过依赖注入的方式,选择自己想要使用的缓存方式。
  • 相关阅读:
    nginx uwsgi django
    ubuntu config proxy
    jdbc调用sparksql
    jdbc调用sparksql on yarn
    JDK错误
    JDK错误
    docker错误
    docker错误
    Django网站直接使用supervisor部署
    Django网站直接使用supervisor部署
  • 原文地址:https://www.cnblogs.com/zhaoshujie/p/9594663.html
Copyright © 2011-2022 走看看