1. 程式人生 > >白話面向物件的六大原則

白話面向物件的六大原則

概念介紹

  1. 單一職責原則 (Single Responsibility Principle) : 一個類中應該是一組相關性很高的函式,資料的封裝.即不能把兩個完全不同的功能放在一個類中,但是這個類或者函式職責的劃分就因人而異了.
  2. 開閉原則 (Open Close Principle) :軟體中的物件(類,模組,函式等)應該對於擴充套件開放,對於修改封閉.即提倡我們應該通過 繼承 或者 實現 介面的方式去擴充套件原有類的功能,儘量不直接去修改原有類的內容.
  3. 里氏替換原則 (Liskov Substitution Principle) : 所有引用了基類的地方都可以使用其子類.這個原則很好的體現的面向物件的繼承和多型兩大特點, 里氏和開閉原則一般都是同時出現.
  4. 依賴倒置原則 (Dependence Inversion Principle) :模組間的依賴通過抽象發生,實現類之間不發生直接的依賴關係,即依賴關係通過介面或者抽象類產生.
  5. 介面隔離原則 (Interface Segregation Principles) : 讓客戶端依賴的介面儘可能的小.
  6. 迪米特原則 (Law of Demeter) :最小知道原則,一個物件應該對其它物件有最少的瞭解.即只需要知道和它有直接關係的物件,其它的不用關心,這樣耦合度就不大

類圖關係

例子類圖關係

程式碼例項

MainActivity

public class MainActivity extends Activity
{
private ImageView mImageView; private String mImageUrl = "http://img.my.csdn.net/uploads/201407/26/1406383291_8239.jpg"; ImageLoader mImageLoader = new ImageLoader(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override
protected void onResume() { super.onResume(); mImageView = (ImageView)findViewById(R.id.show_imageview); mImageLoader.setImageCache(new DoubleCache()); mImageLoader.displayImage(mImageUrl, mImageView); } }

ImageLoader

public class ImageLoader {
    ImageCache mImageCache = new MemoryCache();
    private static final int MSG_UPDATE_IMAGE = 2018;
    private ImageView mImageView;
    ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime()
            .availableProcessors());


    public Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_UPDATE_IMAGE:
                    if (mImageView != null) {
                        mImageView.setImageBitmap((Bitmap) msg.obj);
                    }
            }
        }
    };

    public void setImageCache(ImageCache cache) {
        mImageCache = cache;
    }

    public void displayImage(String imageUrl, ImageView imageView) {
        Bitmap bitmap = mImageCache.get(imageUrl);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
            return;
        }
        submitLoadRequest(imageUrl, imageView);
    }

    public void submitLoadRequest(final String imageUrl, final ImageView imageView) {
        imageView.setTag(imageUrl);
        mImageView = imageView;
        mExecutorService.submit(new Runnable() {
            @Override
            public void run() {
                Bitmap bitmap = downloadImage(imageUrl);
                if (bitmap == null) {
                    return;
                }
                if (imageView.getTag().equals(imageUrl)) {
                    mHandler.removeMessages(MSG_UPDATE_IMAGE);
                    Message message = new Message();
                    message.what = MSG_UPDATE_IMAGE;
                    message.obj = bitmap;
                    mHandler.sendMessage(message);
                }
                mImageCache.put(imageUrl, 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 (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return bitmap;
    }
}

ImageCache

public interface ImageCache {
    public Bitmap get(String url);
    public void put(String url, Bitmap bmp);
}

DoubleCache

public class DoubleCache implements ImageCache {

    ImageCache mMemoryCache = new MemoryCache();
    DiskCache mDiskCache = new DiskCache();

    @Override
    public Bitmap get(String url) {
        Bitmap bitmap = mMemoryCache.get(url);
        if (bitmap == null) {
            bitmap = mDiskCache.get(url);
        }
        return bitmap;
    }

    @Override
    public void put(String url, Bitmap bmp) {
        mMemoryCache.put(url, bmp);
        mDiskCache.put(url, bmp);
    }
}

DiskCache

public class DiskCache implements ImageCache {

    static String cacheDir = "sdcard/cache/";
    public String mImageName;

    @Override
    public Bitmap get(String url) {
        mImageName = getImageName(url);
        if (fileIsExists(cacheDir + mImageName)) {
            return BitmapFactory.decodeFile(cacheDir + mImageName);
        }
        return null;
    }

    @Override
    public void put(String url, Bitmap bmp) {
        FileOutputStream fileOutputStream = null;
        try {
            File file = new File(cacheDir + mImageName);
            fileOutputStream = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public boolean fileIsExists(String strFile) {
        try {
            File f=new File(strFile);
            if(!f.exists())
            {
                return false;
            }

        } catch (Exception e) {
            return false;
        }

        return true;
    }

    public String getImageName(String url) {
        Pattern p = Pattern.compile("[^/]*$");
        String [] str = p.split(url);
        Log.d("yigit","str[0] = "+str[0]);//前面部分
        // System.out.println(url.substring(str[0].length()));//後面部分
        String imageName = url.substring(str[0].length());//後面部分
        Log.d("yigit","imageName = "+imageName);
        return imageName;
    }
}

MemoryCache

public class MemoryCache implements ImageCache {

    private LruCache<String, Bitmap> mMemeryCache;

    public MemoryCache() {
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;
        mMemeryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getRowBytes() * value.getHeight() / 1024; //Since API Level 1
//                return value.getByteCount() / 1024;  //Since API Level 12
            }
        };
    }

    @Override
    public Bitmap get(String url) {
        return mMemeryCache.get(url);
    }

    @Override
    public void put(String url, Bitmap bmp) {
        mMemeryCache.put(url, bmp);
    }
}

參考 Android原始碼設計模式解析與實踐 – 何紅輝 關愛名