1、面向对象的六大原则

基于《Android源码设计模式解析与实战》

  • 单一职责原则
  • 开闭原则
  • 里氏替换原则
  • 依赖倒置原则
  • 接口隔离原则
  • 迪米特原则

单一职责原则

定义:就一个类而言,应该仅有一个引起它变化的原因。
简单来说就是把类的功能拆分开,不要那么臃肿,不然扩展性非常差。
我接着拿书中的例子来说事:
一开始是:


单一职责原则-bug.png

将缓存的处理和显示都放到了一个类里面,代码严重耦合;
明确一些单一职责原则,重构:


单一职责原则.png

将图片加载和图片缓存的职责单独提出来了。

开闭原则

定义:软件中的对象(类、模块、函数等)应该对于扩展是开放的,但是对于修改是封闭的。
简单来说就是面向抽象编程,就比如说我们去点菜,假设就一次机会,你说你要吃猪肉,这要是没有那岂不是糟糕,但是如果你说你要吃肉,这就有的聊了,鸡肉猪肉牛肉可以随便上,总有一样有的;
还是借助书上的例子:
在此基础上需要本地缓存


开闭原则-bug.png

两种缓存策略在displayImage中通过isUseDiskCache来判断;该策略的bug就是用户只能在这两种策略中二选一,不能同时使用内存缓存和磁盘缓存;


开闭原则-bug2.png

通过设置两个标签可以使用内存缓存/磁盘缓存/双缓存;这边的问题是每次加入新的缓存实现就要修改代码,而且用户还不能自定义缓存;


开闭原则.png

这样ImageLoader只依赖ImageCache这个抽象,用户可通过实现这个接口来完成自定义缓存;
对扩展是开放的,对修改是封闭的。主要是通过抽象来实现;

里氏替换原则

定义:所有引用基类的地方必须能透明地使用其子类的对象。


里氏替换原则.png

主要是通过继承和多态的形式提高代码的扩展性。

依赖倒置原则

定义:一种特定的解耦形式,使得高层次的模块不依赖与低层次的模块的实现细节的目的,依赖模块被颠倒了。
关键点:

  • 高层模块不应该依赖低层模块,二者都应该依赖抽象;
  • 抽象不应该依赖细节;
  • 细节应该依赖抽象;

Java中,抽象就是指接口或抽象类,两者都是不能直接被实例化的;细节就是实现类;

模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系;

依赖倒置原则.png

ImageCache抽象,这里就是当用户使用不同的缓存实现时,直接通过依赖注入即可,保证了系统的灵活性。

主要思想就是依赖抽象。

接口隔离原则

定义:客户端不应该依赖它不需要的接口;类间的依赖关系应该建立在最小的接口上。

接口隔离原则将非常庞大、臃肿的接口拆分成更小的和更具体的接口,这样客户将会只需要知道他们感兴趣的方法。

import java.io.Closeable;
import java.io.IOException;

/**
 * 
 * @author xy
 *
 */
public class CloseUtils {
    private CloseUtils() {
    }

    /**
     * 关闭Closeable对象
     * 
     * @param closeables
     */
    public static void closeQuietly(Closeable... closeables) {
        if (null != closeables) {
            for (Closeable closeable : closeables) {
                if (null != closeable) {
                    try {
                        closeable.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

只要实现了Closeable这个接口,就可以通过这个方法关闭,而不用去关注其他的东西。
举个简单的例子:
人的一生的生活习惯有很多:吃什么,喝什么,玩什么。。。。。。
用接口来描述行为:

package com.principle.isp;

public interface Life {
    /**
     * 吃啥
     */
    void eatWhat();

    /**
     * 怎么吃
     */
    void eatHow();

    /**
     * 在哪吃
     */
    void watWhere();

    /**
     * 喝啥
     */
    void drinkWhat();

    /**
     * 怎么喝
     */
    void drinkHow();

    /**
     * 去哪喝
     */
    void drinkWhere();
    /**
     * 等等......
     */
}

如果我们想研究一个人的生活习惯--吃的时候,我们要实现这个接口,就抛不开喝还有玩等等;但是如果我们使用接口隔离:

package com.principle.isp;

/**
 * 
 * @author xy
 *
 */
public interface Eat {

    /**
     * 吃啥
     */
    void eatWhat();

    /**
     * 怎么吃
     */
    void eatHow();

    /**
     * 在哪吃
     */
    void watWhere();

}
package com.principle.isp;

/**
 * 
 * @author xy
 *
 */
public interface Drink {

    /**
     * 喝啥
     */
    void drinkWhat();

    /**
     * 怎么喝
     */
    void drinkHow();

    /**
     * 去哪喝
     */
    void drinkWhere();

}

这样当我研究吃的时候,我可以只关注吃,研究喝的时候只关注喝;
就像我想学设计模式、算法、混合开发、网络、h5等等,我要是每个都去关注一下,我不知道要耗费多少时间,还不一定会学的通透,还不如我就学习设计模式,等我设计模式学好了,我再去只关注算法,每次我只关于一样,平时融会贯通;不好意思,牛逼吹大了,我给自己一巴掌。

迪米特原则

定义:一个对象应该对其他对象有最少的了解。

一个类应该对自己需要耦合或调用的类知道的最少,类的内部如何实现与调用者或者依赖着没有关系,调用者或者依赖着只需要知道它需要的方法即可,其他的可一概不用管。类与类之间关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。

迪米特原则-bug.png

中介和房源,客户耦合,客户和房源、中介耦合,耦合太严重;


迪米特原则.png

中介和房源、客户打交道;而客户只与中介打交道,降低耦合度。


现在可以来总结一下:主要有六个原则:

  • 单一职责原则
  • 开闭原则
  • 里氏替换原则
  • 依赖倒置原则
  • 接口隔离原则
  • 迪米特原则

简单点概括就是:要功能细化,面向抽象,降低耦合。

/**
 * 1、功能要单一;
 * 2、多态抽象
 * 3、降低耦合
 * 
 * 我就以一部仙侠的大背景来展开描述;
 * 上古时期,群魔乱舞,世人可不堪言,急需大能者救世;
 * 救世分两种:救人和救世(单一职责)
 * 目前世间有大造化者:儒释道,统称救世主,救世主集团封锁了整片战场;主要你有大能力,就可以得到救世主铭牌,就可以进入主战场,
 * 主战场的大门识别系统识别铭牌(依赖倒置原则);主战场里面有大阵,当一个阵法师被消灭后,他的族人后代就继续顶替他,毕竟他们家都会xxxx大阵(里氏替换原则)
 * 救世主铭牌是根据个人的功法,经验,德行来评判,不限制具体的考核(开闭原则)
 * 每个救世主集团要根据不同的任务类型去派遣不同的弟子(接口隔离原则):炼制武器,炼制丹药
 * 救世主只负责救世,由任务堂统一分配任务,任务堂接触受难者,了解任务,接触弟子,分配任务(迪米特原则)
 *
 */

你可能感兴趣的:(1、面向对象的六大原则)