目录
1.概述
接口隔离原则(Interface Segregation Principle,ISP), 2002年Robert C.Martin 给"接口隔离原则"的定义是:客户端不应该被迫依赖于它不适用的方法。该原则还有另外一个定义:一个类对另一个类的依赖应该建立在最小的接口上。
接口隔离原则要求程序员尽量将臃肿庞大的接口拆分成更小的和更具体的接口,让接口中只包含客户感兴趣的方法。接口隔离是为了高内聚,低耦合。
在具体应用接口隔离原则时,应该根据以下几个规则衡量:
1.接口尽量小,但是要有限度。一个接口只服务于一个子模块或业务逻辑。
2.为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法。
3.了解环境,拒绝盲从。每个项目或产品都有特定的环境因素,环境不同,接口拆分的标准就不同,要深入了解业务逻辑。
4.提高内聚,减少对外交互。让接口用最少的方法完成最多的事情。
2.业务场景
对于接口隔离的场景,在平时简单的业务开发中可能不会遇到,也可能体现得不明显。《王者荣耀》里有很多英雄,可以分为射手、战士、刺客等,每个英雄有三种技能。这些技能该如何定义,让每个英雄实现相应的技能效果呢?
3.运用设计原则前代码实现
3.1.代码实现
技能ISkill.java
package chapter02.isp;
/**
* 英雄技能
*/
public interface ISkill {
// 射箭
void doArchery();
// 隐袭
void doInvisible();
// 沉默
void doSilent();
// 眩晕
void doVertigo();
}
后羿类 HeroHouYi.java
package chapter02.isp;
/**
* 英雄后裔
*/
public class HeroHouYi implements ISkill{
@Override
public void doArchery() {
System.out.println("后羿的灼日之矢");
}
@Override
public void doInvisible() {
System.out.println("后羿的隐身技能");
}
@Override
public void doSilent() {
System.out.println("后羿的沉默技能");
}
@Override
public void doVertigo() {
//无此技能的实现
}
}
廉颇类 HeroLianPo.java
package chapter02.isp;
/**
* 英雄廉颇
*/
public class HeroLianPo implements ISkill{
@Override
public void doArchery() {
//无此技能
}
@Override
public void doInvisible() {
System.out.println("廉颇的隐身技能");
}
@Override
public void doSilent() {
System.out.println("廉颇的沉默技能");
}
@Override
public void doVertigo() {
System.out.println("廉颇的眩晕技能");
}
}
3.2.总结
1.每个英雄的实现类里都有一个和自己无关的接口实现类,非常不符合设计模式,也不易于维护。因为不仅无法控制外部的调用,还需要维护对应的文档,来说明这个接口不需要实现。如果有更多这样的接口,就会变得非常麻烦。
4.运用设计原则后代码实现
按照接口隔离原则的约定,应该在确保合理的情况下,把接口细分。保证一个松散的结构,也就是把技能拆分出来,每个英雄都可以按需继承实现。
4.1.代码实现
ISkillArchery.java
package chapter02.isp;
public interface ISkillArchery {
//灼日之矢
void doArchery();
}
ISkillInvisible.java
package chapter02.isp;
public interface ISkillInvisible {
//隐袭
void doInvisible();
}
ISkillSilent.java
package chapter02.isp;
public interface ISkillSilent {
//沉默
void doSilent();
}
ISkillVertigo.java
package chapter02.isp;
public interface ISkillVertigo {
//眩晕
void doVertigo();
}
HeroHouYiExt.java
package chapter02.isp;
public class HeroHouYiExt implements ISkillArchery,ISkillInvisible,ISkillSilent{
@Override
public void doArchery() {
System.out.println("后羿的灼日之矢");
}
@Override
public void doInvisible() {
System.out.println("后羿的隐身技能");
}
@Override
public void doSilent() {
System.out.println("后羿的沉默技能");
}
}
HeroLianPoExt.java
package chapter02.isp;
public class HeroLianPoExt implements ISkillInvisible, ISkillSilent, ISkillVertigo {
@Override
public void doInvisible() {
System.out.println("廉颇的隐身技能");
}
@Override
public void doSilent() {
System.out.println("廉颇的沉默技能");
}
@Override
public void doVertigo() {
System.out.println("廉颇的眩晕技能");
}
}
4.2.总结
1.现在可以看到这两个英雄的类都按需实现了自己需要的技能接口。这样的实现方式就可以避免一些本身不属于自己的技能还需要不断地用文档的方式进行维护,同时提高了代码的可靠性,在别人接手或者修改时,可以降低开发成本和维护风险。