ISP = Interface Segregation Principle
 
ISP的定义如下:
1、客户端不应该依赖他不需要的接口
2、一个类对另外一个类的依赖性应该是建立在最小的接口上
3、不应当将不同的接口合并在一起,形成一个臃肿的大接口,这是对接口的污染
4、使用多个专门的接口要比使用单一的总接口要好
 
 
ISP的几个使用原则
1、根据接口隔离原则拆分接口时,首先必须满足单一职责原则: 没有哪个设计可以十全十美的考虑到所有的设计原则,有些设计原则之间就可能出现冲突,就如同单一职责原则和接口隔离原则,一个考虑的是接口的职责的单一性,一个考虑的是方法设计的专业性(尽可能的少),必然是会出现冲突。在出现冲突时,尽量以单一职责为主,当然这也要考虑具体的情况。
2、提高高内聚: 提高接口,类,模块的处理能力,减少对外的交互。比如你给杀手提交了一个订单,要求他在一周之内杀一个人,一周后杀手完成了任务,这种不讲条件完成任务的表现就是高内聚。具体来说就是:要求在接口中尽量少公布public方法,接口是对外的承诺,承诺越少对系统的开发越有利,变更的风险就越小,也有利于降低成本。
3、定制服务: 单独为一个个体提供优良服务(只提供访问者需要的方法)。
4、接口设计要有限度: 根据经验判断
 
 
接口隔离原则和单一职责原则就是一个硬币的两面,他们说的其实是一回事。
只是接口隔离原则是站在服务调用者角度看问题,单一职责原则是站在服务提供者的角度看。
 
 
===========================================================================================
契约是怎么回事呢?
契约就是在说两件事,甲方在契约里说我不会多要,乙方会在契约里说我不会少给。
乙方的不会少给是比较容易做到的,因为当一个类实现一个接口的时候,他必须要实现接口里的所有方法。如果你不想实现所有的方法,你留下了抽象方法,那你这个类就是抽象类,不能被实例化,即你不是一个完整的服务提供者。所以说乙方不会少给,是强制性的。
甲方不会多要是软性的规定,他是个设计上的东西,需要我们用一些设计原则去约束和控制大家写代码。因为编译器是能检测出乙方是不是少给,没法检查出来甲方是不是多要了。
 
那么我怎么知道甲方有没有多要呢?很简单,就看传递给调用者接口类型里,有没有一直没有被调用到的函数成员,如果有,就说明传递进来的接口类型太大了(太胖了),换句话说 胖接口就是这个接口是由两个或两个以上本质不同的小一点接口合并起来的,把大接口传递进来,只能一部分接口被调用到,另一部分就多余出来了。
根据胖接口的产生原因不同,违反接口隔离原则可能带来的不好的后果基本上有两个:
1、第一种情况,设计的时候有问题,把太多的功能接口包含进来,那其中必然有一部分功能永远用不到,也就自然违反了接口隔离原则。
  我们看一下实例:
   场景介绍: 一对小情侣,一天女生给男生打电话,告诉他车被追尾了,哭的梨花带雨。小男生情商高,哄小女生说 不要紧,明天给你买辆坦克,就不怕追尾了。(前提是小女生不能开炮,只能开~~~~)
 
 
   第一版的实现=》小女生只会开汽车,不会开别的

#region 车辆接口和实现

    interface IVehicle
{
void Run();
} class Car : IVehicle
{
public void Run()
{
Console.WriteLine("Car is Running");
}
}
class Truck : IVehicle
{
public void Run()
{
Console.WriteLine("Truck is Running");
}
} #endregion

驾驶员类:

class Driver
{
private IVehicle _vehicle;
public Driver(IVehicle vehicle)
{
_vehicle = vehicle;
}
public void Drive()
{
_vehicle.Run();
}
}

服务调用方:

   var driver = new Driver(new Car());//开汽车
driver = new Driver(new Truck());//开卡车
driver.Drive(); //这时候你会发现,如果小女生想要开坦克的话,目前是满足不了的
//因为Driver构造参数传递的是IVehicle接口,不是ITank接口
//如果想要满足小女生开坦克上街的愿望,就必须改造Driver,传递ITank接口,请看下一个例子 Console.ReadKey();

第二版的实现=》小女生能开坦克,但是却不能开汽车了

 class Driver
{
private ITank _tank;
public Driver(ITank tank)
{
_tank = tank;
}
public void Drive()
{
_tank.Run();
}
}
   var driver = new Driver(new HeavyTank());//开坦克
driver.Drive(); // 这时候你会发现, 小女生能开坦克上街了,但是你又会发现,小女生现在只会开坦克了,不会开车了
// 问题出现在哪里呢?
// 我们把一个胖接口(ITank)传递进来,这个胖接口中有一个我们永远用不到的功能,就是fire。
// 所以现在这个设计是违反了接口隔离原则
// 具体改造请看下一个例子 Console.ReadKey();
   第三版的实现=》符合接口隔离原则,小女生能开坦克,也能开汽车了。
#region 车辆接口和实现

    interface IVehicle
{
void Run();
} class Car : IVehicle
{
public void Run()
{
Console.WriteLine("Car is Running");
}
}
class Truck : IVehicle
{
public void Run()
{
Console.WriteLine("Truck is Running");
}
} #endregion
interface IWeapon
{
void Fire();
}
  interface ITank:IVehicle,IWeapon
{
}
class LightTank : ITank
{
public void Fire()
{
Console.WriteLine("Boom!");
} public void Run()
{
Console.WriteLine("Ka Ka Ka!");
}
} class HeavyTank : ITank
{
public void Fire()
{
Console.WriteLine("Boom!!!!!!!!");
} public void Run()
{
Console.WriteLine("Ka!!! Ka!!!! Ka!!!!!!");
}
}

驾驶员类:

  class Driver
{
private IVehicle _vehicle;
public Driver(IVehicle vehicle)
{
_vehicle = vehicle;
}
public void Drive()
{
_vehicle.Run();
}
}

服务调用方:

      //接口隔离的原则是 服务的调用方不会都要
//本例子中服务的调用方的需求很简单,这是要求会run,不要求fire
//因此原先的ITank接口中自己包含的fire和run就符合胖接口的规则,他提供了多余的接口给调用方
//因此把ITank接口隔离开是对的
var driver = new Driver(new HeavyTank());//开坦克
driver.Drive();
driver = new Driver(new Car());//开汽车
driver.Drive(); Console.ReadKey();

 第二种情况明天继续,哇哈哈~~~~~~~~~~
 

面向对象的六大原则之 接口隔离原则——ISP的更多相关文章

  1. 设计原则:接口隔离原则(ISP)

    接口隔离原则的英文是Interface Segregation Principle,缩写就是ISP.与里氏替换原则一样其定义同样有两种 定义1: Clients should not be force ...

  2. IOS设计模式的六大设计原则之接口隔离原则(ISP,Interface Segregation Principle)

    定义 客户端不应该依赖它不需要的接口: 一个类对另一个类的依赖应该建立在最小的接口上. 定义解读 定义包含三层含义: 一个类对另一个类的依赖应该建立在最小的接口上: 一个接口代表一个角色,不应该将不同 ...

  3. 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP

    前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第4篇,接口隔离原则ISP(The Interface Segregation Principle). 英文原文:htt ...

  4. 设计模式 第一天 UML图,设计模式原则:开闭原则、依赖倒转原则、接口隔离原则、合成复用原则、迪米特法则,简单工厂模式

    1 课程大纲 2 UML的概述 总结: UML unified model language 统一建模语言 一共有十种图: 类图 用例图 时序图 * 对象图 包图 组件图 部署图 协作图 状态图 (最 ...

  5. 最简单直接地理解Java软件设计原则之接口隔离原则

    理论性知识 定义 接口隔离原则, Interface Segregation Principle,(ISP). 一个类对应一个类的依赖应该建立在最小的接口上: 建立单一接口,不要建立庞大臃肿的接口: ...

  6. 设计模式学习--面向对象的5条设计原则之接口隔离原则--ISP

    一.ISP简介(ISP--Interface Segregation Principle): 使用多个专门的接口比使用单一的总接口要好.一个类对另外一个类的依赖性应当是建立在最小的接口上的.一个接口代 ...

  7. C# 实例解释面向对象编程中的接口隔离原则

    在面向对象编程中,SOLID 是五个设计原则的首字母缩写,旨在使软件设计更易于理解.灵活和可维护.这些原则是由美国软件工程师和讲师罗伯特·C·马丁(Robert Cecil Martin)提出的许多原 ...

  8. [设计模式]<<设计模式之禅>>关于接口隔离原则

    在讲接口隔离原则之前,先明确一下我们的主角——接口.接口分为两种: ● 实例接口(Object Interface),在Java中声明一个类,然后用new关键字产生一个实例,它是对一个类型的事物的描述 ...

  9. 设计模式之六大原则——接口隔离原则(ISP)

    设计模式之六大原则——接口隔离原则(ISP)  转载于:http://www.cnblogs.com/muzongyan/archive/2010/08/04/1792528.html 接口隔离原则 ...

随机推荐

  1. java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11GraphicsEnvironment

    请求验证码时后台报错:java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11GraphicsEnvironment ...

  2. 微服务:Eureka+Zuul+Ribbon+Feign+Hystrix构建微服务架构

    原文地址:http://blog.csdn.net/qq_18675693/article/details/53282031 本案例将打架一个微服务框架,参考来源官方参考文档 微服务:是什么?网上有一 ...

  3. PHP代码篇(三)--常用方法

    模块下不间断更新,PHP常用方法,欢迎留言! 一.递归删除指定目录下所有文件及文件夹 /** * 递归删除指定目录下所有文件及文件夹 * @param unknown $path,删除路径 */ fu ...

  4. [转]5 种使用 Python 代码轻松实现数据可视化的方法

    数据可视化是数据科学家工作中的重要组成部分.在项目的早期阶段,你通常会进行探索性数据分析(Exploratory Data Analysis,EDA)以获取对数据的一些理解.创建可视化方法确实有助于使 ...

  5. kettle教程---增量更新

    以下操作都在5.0.1版本下进行开发,其余版本可以进行自动比对 在平时工作当中,会遇到这种情况,而且很常见.比如:增量抽取(每隔2个小时抽取截至到上次抽取时间的记录) 一.操作前提: 存在3张表,源表 ...

  6. 18.Java基础_关键字this及其内存原理

    this使用 this的内存原理 执行函数setName时,首先是创建函数栈空间,然后创建形参name,除此之外还会有一个this(实质是堆内存中对象的首地址),这个this会索引对象的成员变量nam ...

  7. 【cf995】F. Cowmpany Cowmpensation(拉格朗日插值)

    传送门 题意: 给出一颗树,每个结点有取值范围\([1,D]\). 现在有限制条件:对于一个子树,根节点的取值要大于等于子数内各结点的取值. 问有多少种取值方案. 思路: 手画一下发现,对于一颗大小为 ...

  8. 【cf570】D. Tree Requests(dsu on tree)

    传送门 题意: 给出一个以\(1\)为根的有根树.之后有\(m\)个询问,每个询问为\(v_i,h_i\),需要回答以\(v_i\)为根的子树中,深度为\(h_i\)的那些结点所代表的字符能否构成回文 ...

  9. 初学JavaScript正则表达式(十一)

    JavaScript的对象属性 整理自慕课网教学 点此进入

  10. python安装包及批量更新包

    python安装包 # pip安装 pip install pyecharts # 源码安装 - linux git clone https://github.com/pyecharts/pyecha ...