厚积薄发打卡Day114:Debug设计模式:设计原则(二)<接口隔离原则、迪米特法则>
接口隔离原则
定义
用多个专门的接口,而不使用单一的总接口,客户端不应该依赖它不需要的接口
一个类对一个类的依赖应该建立在最小的接口上,建立单一接口,不要建立庞大臃肿的接口
细粒度组装 粗粒度不可拆分
尽量细化接口,接口中的方法尽量少
注意适度原则,一定要适度
优点:符合我们常说的高内聚低耦合的设计思想,从而使得类具有很好的可读性、可扩展性和可维护性。
场景coding
- 动物行为接口类:以兔子🐇和小鸟🐦为例:
/** * Created by Wayne * 动物行为 */ public interface IAnimalAction { void eat(); // 吃 void fly(); // 飞 void swim(); // 游泳 }
public class Bird implements IAnimalAction { @Override public void eat() { } @Override public void fly() { } @Override public void swim() { // TODO: 有些鸟不会游泳 } }
由于动物行为具有多样性,用统一的接口约束不合理,设计过程中违背了接口隔离原则,造成代码冗余等情况。public class Rabbit implements IAnimalAction{ @Override public void eat() { } @Override public void fly() { // todo 兔子不会飞 } @Override public void swim() { // TODO 兔子也不会游泳 } }
-
优化:具体行为动物接口实现
如定义分别定义:吃、飞、睡 三个标准接口
这时候创建类时就可以根据对应的特性去实现:/** * Created by Wayne */ public interface ISwimAnimalAction { void swim(); } /** * Created by Wayne */ public interface IEatAnimalAction { void eat(); } /** * Created by Wayne */ public interface IFlyAnimalAction { void fly(); }
public class Dog implements ISwimAnimalAction, IEatAnimalAction { @Override public void eat() { } @Override public void swim() { } }
public class Chicken implements IEatAnimalAction{ @Override public void eat() { } }
通过自定义接口最小粒度实现。public class Pigeon implements IFlyAnimalAction,IEatAnimalAction{ @Override public void eat() { } @Override public void fly() { } }
接口隔离原则与单一职责原则区别**(3大区别):**
接口隔离原则与单一职责原则区别(3大区别) – mikechen的互联网架构
简单总结:单一职责重点在实现,接口隔离重点在接口
- 单一职责原则注重的是类、接口和方法的职责(注重实现),而接口隔离原则注重的是对接口依赖的隔离;
- 单一职责原则针对的是模块、类的设计,注重的是职责,这是业务逻辑上的划分;
- 接口隔离原则主要约束接口,主要针对抽象和程序整体框架的构建。
尽量用少的接口 完成尽量多的功能
迪米特法则
定义
一个对象应该对其他对象保持最少的了解。又叫最少知道原则。尽量降低类与类之间的耦合
优点:降低类之间的耦合
强调只和明友交流,不和陌生人说话。
- 什么是朋友?
- 出现在成员变量、方法的输入、输出参数中的类称为成员明友类,而出现在方法体内部的类不属于朋友类。
场景coding
老板BOSS让经理Manger去核对数据Data
- 直接操作:BOSS下令让Manger去查Data
public class Boss{ public void commandCheckDataNumber(Manger manger){ List<Data> dataList = new ArrayList<Data>(); // 模拟数据统计操作 for (int i = 0; i < 20; i++) { dataList.add(new Data()); } manger.checkDataNumber(dataList); } }
public class Manger { public void checkDataNumber(List<Data> dataList) { System.out.println("现存数据数量是:" + dataList.size()); } }
public class Data { }
在这里DATA和Manger&Boss都有交互,一定程度上的耦合不符合迪米特法则。public class Test { public static void main(String[] args) { Boss boss = new Boss(); Manger manger = new Manger(); boss.commandCheckDataNumber(manger); } }
- 迪米特优化:这里BOSS和Manger是朋友,Manger和Data是朋友,而Boss跟Data没有直接关系。
public class Boss{ public void commandCheckDataNumber(Manger manger){ manger.checkDataNumber(); } }
public class Manger { public void checkDataNumber() { List<Data> dataList = new ArrayList<Data>(); // 模拟数据统计操作 for (int i = 0; i < 20; i++) { dataList.add(new Data()); } System.out.println("现存数据数量是:" + dataList.size()); } }