走向面向对象的六大原则--迪米特原则

面向对象编程的六大原则


更好的可拓展性--迪米特原则
迪米特原则的英文全称是Law of Demeter,缩写是LOD,也称为最少知识原则。
定义是:一个对象应该对其他对象有最少的了解。
直白的说,就是让对象只与最直接的朋友进行联系。那么什么是最直接朋友呢?每个对象都必然会与其他类有耦合关系,两个对象之间互相耦合就为朋友关系,这种关系类型有很多,比如组合,聚合,依赖。
下面,我们就通过举例来说明迪米特原则

相信在外务工的朋友,都有租房的经历,一般情况下大家都会通过中介找房。我们通过租房进行举例,我们设定条件为:我只要求房子的租金和面积,中介负责将合适的房子介绍给我。以下是代码实例。

// 房子
public class House {
    public float area;
    public float price;

    public House(float area, float price) {
        this.area = area;
        this.price = price;
    }

    @Override
    public String toString() {
        return "House{" +
                "area=" + area +
                ", price=" + price +
                '}';
    }
}
// 中介
public class Agency {
    List<House> mHouses = new ArrayList<>();

    public Agency() {
        for (int i = 0; i < 5; i++) {
            mHouses.add(new House(100 + i, (100 + i) * 200));
        }
    }

    public List<House> getHouses() {
        return mHouses;
    }
}
//租户
public class Tenant {
    public float houseArea;
    public float housePrice;
    public static final float diffPrice = 200.001f;
    public static final float diffArea = 0.00001f;

    public void rentHouse(Agency agency) {
        List<House> mHouses = agency.getHouses();
        for (House house : mHouses) {
            if (isRightHouse(house)) {
                System.out.println("找到合适的房子了!\n" + house.toString());
                break;
            }

        }
    }

    private boolean isRightHouse(House house) {
        return Math.abs(house.price - housePrice) < diffPrice
                && Math.abs(house.area - houseArea) < diffArea;
    }
}

从上面的代码我们可以看到,我们的租户类(Tenant)不仅依赖了中介类(Agency),还要频繁地与我们的房子类(House)打交道。我们的需求是:我只要求房子的租金和面积,中介负责将合适的房子介绍给我。但是现在是我们拿到了一大堆房子数据然后自己进行分析和计算,这样一来,中介的功能就被弱化了,并且导致我们的租户类(Tenant)和房子类(House)的耦合过高,因为作为租户而言,我们必须知道房子(House)的细节。而此时租户类(Tenant)又和中介类(Agency)保持联系。这个时候我们就有必要进行一定的代码调整,去区分清楚,究竟谁是谁的直接朋友,让我们的代码清晰起来。
我们通过需求进行分析,可以得出以下几点:

  • 租户只负责租房,提出房子的大小要求和租金要求,其他的要交给中介来做。
  • 租户不参与房子的分析比对。
  • 中介负责与客户进行交流,并且为客户进行房子的比对和筛选。

如此一来,我们可以根据需求对代码进行如下调整:

public class Agency {
    List<House> mHouses = new ArrayList<>();

    public Agency() {
        for (int i = 0; i < 5; i++) {
            mHouses.add(new House(100 + i, (100 + i) * 200));
        }
    }

    public House rentHouse(float area, float price) {
        for (House house : mHouses) {
            if (isRightHouse(area, price, house)) {
                System.out.println("找到合适的房子了!\n" + house.toString());
                return house;
            }
        }
        return null;
    }

    private boolean isRightHouse(float area, float price, House house) {
        return Math.abs(house.price - price) < Tenant.diffPrice
                && Math.abs(house.area - area) < Tenant.diffArea;
    }
}

public class Tenant {
    public float houseArea;
    public float housePrice;
    public static final float diffPrice = 200.001f;
    public static final float diffArea = 0.00001f;

    public void rentHouse(Agency agency) {
        System.out.println("找到合适的房子了:" + agency.rentHouse(houseArea, housePrice));
    }
}

此处我们经过一些简单的调整,将对房子是否符合要求的判断放到了中介里,这其实本就应该是中介的职责,根据用户设定的条件去寻找房子,找到了就告诉用户就可以了。而用户也不需要知道有多少房源,每个房子是什么样,他只需要询问中介,中介告知结果即可。
从上述代码我们可以看到,我们通过一次简单的代码修改后,代码的耦合性已经降低了很多,同时,他们都达成了与最直接的朋友联系的条件,将各个角色从复杂的关系中抽离出来,使程序的耦合更低,稳定性更好。
这里我们再次回忆一下我们ImageLoader中的代码,就拿SD卡缓存来说,ImageCache就是用户的直接朋友,而SD卡缓存内部却是使用了DiskCache实现,这个DiskCahce就不是用户的直接朋友了,因此,其实用户完全不需要知道有这样的缓存存在,用户只需要和ImageCache打交道就好了,我们之前的代码我再次优化过,使用了JakeWhartonDiskLruCache,最后代码如下:

public void put(String url, Bitmap bitmap) {
    DiskLruCache.Editor editor = null;
    //如果没有在内存缓存和磁盘缓存中找到对对应的缓存,从网络上请求数据
    //写入缓存
    editor = mDiskLruCache.edit(url);
    try {
        if (editor != null) {
            OutputStream out = editor.newOutputStream(0);
            if (writeBitmapToDisk(value, out)) {
                //写入SD卡
                editor.commit();
            } else {
                editor.abort();
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    CloseUtils.colse(out);
}

用户在使用SD卡缓存的时候,根本不知道DiskLruCache的实现,这就很好地对用户隐藏了具体的代码实现。当你能够自己去写DiskLruCache的时候,你就可以随意替换掉此处我们引用的JakeWharton大神的DiskLruCache了。


总结#

一不小心,六个章节的《走向面向对象的六大原则》就到此结束了,在这里感谢何红辉、关爱民先生所著的《Android设计模式》一书,给我了很多启发和灵感,并且示例上提供了很多借鉴。
时间总是很快,快到你都注意不到自己的胡渣子又冒出来了,在我们开发的过程中,最难的不是开发出用户所需要的功能,而是在后续的升级和维护过程中,让系统能够拥抱变化,不因为版本的迭代更新而破坏模块的完整性和代码的条理性,保证代码的低耦合,高可拓展性,高内聚,在经理了N个版本的迭代以后,软件系统依旧能够保持稳健,灵活,清晰的架构。
当然啦,这只是一个理想的情况,代码迭代而引发的坑,我们爬的还少吗?为了少爬坑,为了让自己的代码更漂亮,系统更稳定,我们必须朝着这个方向去努力,遵循面向对象的六大原则,就是我们走出的,第一步
明天的将会写关于单例模式的一些理解和示例,感谢大家的一直支持,我们共同进步!
谢谢。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容