Java设计模式(3:接口隔离原则和迪米特法则详解)
一、接口隔离原则
使用多个接口,而不使用单一的接口,客户端不应该依赖它不需要的接口。尽量的细化接口的职责,降低类的耦合度。
我们先来看一个例子:
小明家附近新开了一家动物园,里面有老虎、鸟儿、长颈鹿.....周末在逛动物园的时候,小明突发奇想,想用一种方式记录一下这些动物的习性,于是他将老虎和鸟儿的习性结合了一下,写了下面这段代码:
动物行为
// 动物行为
public interface Animal {
// 吃
public void eat();
// 游泳
public void swim();
// 飞
public void fly();
}
老虎Tiger
// 老虎
public class Tiger implements Animal {
@Override
public void eat() {
System.out.println("老虎在吃鸡肉.....");
}
@Override
public void swim() {
System.out.println("老虎在游泳.....");
}
@Override
public void fly() {
System.out.println("老虎不能飞.....");
}
}
小鸟Brid
// 小鸟
public class Brid implements Animal {
@Override
public void eat() {
System.out.println("小鸟在吃虫子.....");
}
@Override
public void swim() {
System.out.println("小鸟不会游泳.....");
}
@Override
public void fly() {
System.out.println("小鸟正在飞.....");
}
}
写完上面的三段代码后,小明发现了问题:在
Animal接口的三个方法中,Tiger是不会飞的,所以fly()方法对于Tiger是没有用的;Bird是不会游泳的,所以swim()方法对于Bird是没有用的。这样一来,Brid类和Tiger类都会空置一个方法,对于代码的结构设计来说不太合理。于是,他划掉了上面的三段代码,仔细思索了一会儿,写出了下面这几段代码:
// 游泳
public interface ISwim {
public void swim();
}
// 吃
public interface IEat {
public void eat();
}
// 飞
public interface IFly {
public void fly();
}
小鸟Bird
// 小鸟
public class Brid implements IEat,IFly {
@Override
public void eat() {
System.out.println("小鸟在吃虫子.....");
}
@Override
public void fly() {
System.out.println("小鸟正在飞.....");
}
}
老虎Tiger
// 老虎
public class Tiger implements IEat,ISwim {
@Override
public void eat() {
System.out.println("老虎在吃鸡肉.....");
}
@Override
public void swim() {
System.out.println("老虎在游泳.....");
}
}
这样来看,将
eat、swim、fly三种方法拆分开来,分别放在三个不同的接口里,这样动物拥有哪几种习性就实现哪几个接口,不会再用空置的方法存在,这样看起来也简洁明了,来看看类图:

二、迪米特法则
又被成为最少知道原则,指的是一个对象应该对其他对象保持最少的了解。一个实体类应当尽量少地和其他实体之间发生相互作用,使得系统模块相互独立。形象来说就是:只和朋友交流,不和陌生人说话。
迪米特法则认为,一个对象或方法,它只能够调用以下对象:
- 该对象本身
- 作为参数传进来的对象
- 在方法内创建的对象
我们先来模拟一个超市购物的场景:顾客Customer到收银台结账,收银员PaperBoy负责收钱。
顾客的钱包Wallet
// 钱包
public class Wallet {
// 钱包里装的钱
private Float value;
// 构造器
public Wallet(Float value) {
this.value = value;
}
// 获得钱包里的钱的金额
public Float getMoney(){
return this.value;
}
// 付账时 减钱
public void reduceMoney(Float money){
this.value -= money;
}
}
顾客Customer
// 顾客
public class Customer {
private Wallet wallet = new Wallet(50f);
public Wallet getWallet() {
return wallet;
}
}
收银员PaperBoy
// 收银员
public class PaperBoy {
// 收银员收钱
public void charge(Customer customer,Float money){
Wallet wallet = customer.getWallet();
if (wallet.getMoney() >= money){
System.out.println("顾客付账:" + money +"元");
// 减去 应付的钱
wallet.reduceMoney(money);
System.out.println("钱包里还剩:"+wallet.getMoney()+"元");
} else {
System.out.println("钱包里的金额不够......");
}
}
}
测试、运行
// 测试
public static void main(String[] args) {
PaperBoy paperBoy = new PaperBoy();
Customer customer = new Customer();
paperBoy.charge(customer,20f);
}

从测试代码和运行的结果来看,好像并没有什么问题。让我们来看一下类图:

从类图中我们发现:PaperBoy类与Wallet类有着千丝万缕的关系,顾客(Customer)的钱包(Wallet)好像并不是自己来控制的,而是由收银员(PaperBoy)来决定的,就连钱包(Wallet)里面的钱够不够也是由收银员(PaperBoy)来判断的;相当于顾客(Customer)将自己的钱包(Wallet)暴露给了收银(PaperBoy),这样来看,问题就很严重了,顾客(Customer)的隐私受到了侵犯,说大点就是民事纠纷,是可以上法庭的,可以通过法律追究责任的。所以我们思考良久,将上述代码改成下面这般:
钱包Wallet类不变,顾客Customer去掉给出钱包的getWallet()方法,增加付钱的pay()方法:
// 顾客
public class Customer {
private Wallet wallet = new Wallet(50f);
// 顾客自己付钱
public void pay(Float money){
if (wallet.getMoney() >= money){
System.out.println("顾客付账:" + money +"元");
// 减去 应付的钱
wallet.reduceMoney(money);
System.out.println("钱包里还剩:"+wallet.getMoney()+"元");
} else {
System.out.println("钱包里的金额不够......");
}
}
}
收银员PaperBoy类中的charge()方法中的代码删除原有的逻辑,改为调用顾客Customer类中的付钱pay()方法:
// 收银员
public class PaperBoy {
// 收银员收钱
public void charge(Customer customer,Float money){
customer.pay(money);
}
}
测试代码不变,我们再来看看类图:

从类的结构图来看:收银员PaperBoy只和顾客Customer有联系,钱包Wallet只和顾客Customer有联系。再此情况下,如果把钱包Wallet也当作一个人来看的话,这个就是如下的关系:
- 顾客
Customer和钱包Wallet是朋友 - 顾客
Customer和收银员PaperBoy是朋友 - 钱包
Wallet和收银员PaperBoy是陌生人
这个就符合我们所说的迪米特法则中的核心:只和朋友交流,不和陌生人说话。
Java设计模式(3:接口隔离原则和迪米特法则详解)的更多相关文章
- 设计模式之接口隔离原则(ISP)
一.定义: ISP:Interface Segregation Principle 接口隔离原则表明客户端不应该被强迫实现一些他们不会使用的接口,应该把胖接口中的方法分组,然后用多个接口代替它,每个接 ...
- IOS设计模式的六大设计原则之迪米特法则(LOD,Law Of Demeter)
定义 狭义的迪米特法则定义:也叫最少知识原则(LKP,Least Knowledge Principle).如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用.如果其中的一个类需要调用 ...
- 想真正了解JAVA设计模式看着一篇就够了。 详解+代码实例
Java 设计模式 设计模式是对大家实际工作中写的各种代码进行高层次抽象的总结 设计模式分为 23 种经典的模式,根据用途我们又可以分为三大类.分别是创建型模式.结构型模式和行为型模式 列举几种设 ...
- 设计模式 第一天 UML图,设计模式原则:开闭原则、依赖倒转原则、接口隔离原则、合成复用原则、迪米特法则,简单工厂模式
1 课程大纲 2 UML的概述 总结: UML unified model language 统一建模语言 一共有十种图: 类图 用例图 时序图 * 对象图 包图 组件图 部署图 协作图 状态图 (最 ...
- java设计模式学习笔记--接口隔离原则
接口隔离原则简述 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应建立在最小的接口上 应用场景 如下UML图 类A通过接口Interface1依赖类B,类C通过接口Interface1依赖类 ...
- [设计模式]<<设计模式之禅>>关于接口隔离原则
在讲接口隔离原则之前,先明确一下我们的主角——接口.接口分为两种: ● 实例接口(Object Interface),在Java中声明一个类,然后用new关键字产生一个实例,它是对一个类型的事物的描述 ...
- ZT 设计模式六大原则(4):接口隔离原则
设计模式六大原则(4):接口隔离原则 分类: 设计模式 2012-02-27 08:32 17948人阅读 评论(21) 收藏 举报 设计模式classinterfacecstring框架 定义:客户 ...
- C#软件设计——小话设计模式原则之:接口隔离原则ISP
前言:有朋友问我,设计模式原则这些东西在园子里都讨论烂了,一搜一大把的资料,还花这么大力气去整这个干嘛.博主不得不承认,园子里确实很多这方面的文章,并且不乏出色的博文.博主的想法是,既然要完善知识体系 ...
- 设计模式之六大原则——接口隔离原则(ISP)
设计模式之六大原则——接口隔离原则(ISP) 转载于:http://www.cnblogs.com/muzongyan/archive/2010/08/04/1792528.html 接口隔离原则 ...
随机推荐
- 010 Editor体验
源代码的我们现在拥有各式各样的IDE和编辑器可以去查看,但二进制文件对于大多数软件只能做到显示16进制,而不能按照文件类型的格式去显示.今天我们就用dex文件让010 show. 安装软件: http ...
- MS08_067漏洞攻击
MS08_067 MS08_067是典型的缓冲区溢出漏洞,Windows的Server服务在处理特制RPC请求时存在缓冲区溢出漏洞,远程攻击者可以通过发送恶意的RPC请求触发这个溢出,导致完全入侵用户 ...
- OpenSSL相关漏洞
目录 心脏出血漏洞(CVE-2014-0160) OpenSSL CCS注入漏洞(CVE-2014-0224) OpenSSL FREAK Attack漏洞(CVE-2015-0204) TLS/SS ...
- HashMap实现原理一步一步分析(1-put方法源码整体过程)
各位同学大家好, 今天给大家分享一下HashMap内部的实现原理, 这一块也是在面试过程当中基础部分被问得比较多的一部分. 想要搞清楚HashMap内部的实现原理,我们需要先对一些基本的概念有一些了解 ...
- vue 2.9.6升级到最新版本
在看文档https://cli.vuejs.org/zh/guide/installation.html中,按步骤升级vue: 于是就先通过 npm uninstall vue-cli -g卸载vue ...
- 详解Tomcat核心配置、http协议
Tomcat服务器 Tomcat配置与部署(IDEA) https://www.cnblogs.com/gonghr/p/14731266.html Tomcat手工创建和打包第一个Web工程 在ap ...
- net5学习笔记---依赖注入
小王的故事 小王去上班 小王是个程序员,每个工作日他都要去上班,诸多交通工具他最喜欢的交通工具是骑电车.在骑行的过程中放空自己使他很快. 突然有一天天气预报说近期有很大的雨,小王再想骑电车去上 ...
- Nmap浅析(1)——主机发现
主机发现 当网络不通时,Ping一下网关来检查网关是否正常.当测试的目标是一个网络时,其中在线的主机才是目标,那么就需要技术来找出这些目标. 技术的方法大都与TCP/IP协议族中的协议相对应. ...
- MakeCode图形编程应用在micro:bit上的多工性能实测
1. 简述 本文不涉及对测试中所用到的设备或软件的推广. micro:bit 是一款由英国广播电视公司(BBC)为青少年编程教育设计,并由微软,三星,ARM,英国兰卡斯特大学等合作伙伴共同完成开发的微 ...
- ES6对象的新增方法的使用
Object.assign Object Object.assign(target, ...sources) 将所有可枚举属性的值从一个或多个源对象复制到目标对象 参数: target 目标对象 so ...