uml结构图讲解(概述耦合UML)
uml结构图讲解(概述耦合UML)第 ② 点,还是在讨论要进行抽象的问题,抽象是高层,具体细节是底层,这和前一点也是契合的,正式说明了一条非常关键的原则 “面向接口编程,而非针对现实编程”先解释第 ① 点,其实这一点在我们以往的分层开发中,就已经用过了,例如我们的业务层 Service(高层模块)就没有依赖数据访问层 Dao/Mapper(低层模块),我们都通过 Mapper 的接口进行访问,这种情况下,如果数据访问层的细节发生了变化,那么也不会影响到业务层,但是如果直接依赖于实现,那么就会影响巨大取消鸟和几维鸟的继承关系,定义鸟和几维鸟更一般的父类,动物类定义:
但是几维鸟是不能飞行的,所别的鸟通过 setSpeed 方法都能附一个有效的值,但是几维鸟就不得不重写这个 setSpeed 方法,让其设置 flySpeed 为 0,这样已经违反了里氏替换原则
面对子类如果不能完整的实现父类的方法,或者父类的方法已经在子类中发生了“异变”,就例如这里几维鸟特殊的 setSpeed 方法,则一般选择断开父类和子类的继承关系,重新设计关系
例如:
取消鸟和几维鸟的继承关系,定义鸟和几维鸟更一般的父类,动物类
(三) 依赖倒置定义:
- ① 高层模块不应该依赖低层模块,两者都应该依赖其抽象
- ② 抽象不应该依赖细节,细节应该依赖抽象
先解释第 ① 点,其实这一点在我们以往的分层开发中,就已经用过了,例如我们的业务层 Service(高层模块)就没有依赖数据访问层 Dao/Mapper(低层模块),我们都通过 Mapper 的接口进行访问,这种情况下,如果数据访问层的细节发生了变化,那么也不会影响到业务层,但是如果直接依赖于实现,那么就会影响巨大
第 ② 点,还是在讨论要进行抽象的问题,抽象是高层,具体细节是底层,这和前一点也是契合的,正式说明了一条非常关键的原则 “面向接口编程,而非针对现实编程”
举个例子
例如一个 Client 客户想访问学校的 readBook 方法,可以这么写
public class Client {
public void read(ASchool aSchool){
System.out.println(aSchool.readBook());
}
}
复制代码
但是,这个地方其实就出现了一个比较大的问题,我们就是直接依赖了具体,而不是抽象,当我们想要查看另一个B学校的 readBook 方法,就需要将代码修改为
public class Client {
public void read(BSchool bSchool){
System.out.println(bSchool.readBook());
}
}
复制代码
但是开闭原则规定,对修改关闭,所以明显违背了开闭原则,如果我们将代码抽象出来,以接口访问就可以解决
定义学校接口 ISchool (I 是大写的 i 只是命名习惯问题,无特殊意义)
public interface ISchool {
String readBook();
}
复制代码