# 开-闭原则(OCP)
设计总原则,其实原则依附它。
一个软件实体应当对扩展开放,对修改关闭。
> “对可变性的封装原则”讲的是找到一个系统的可变因素,将之封装起来。
考虑你允许什么发生改变而不让这一变化导致重新设计。
继承应当被看做是封装变化的方法,而不应当被认为是从一般的对象生成特殊的对象的方法。
实现开-闭原则原则的重要步骤就是抽象化。
# 里氏替换原则(LSP)
任何基类出现的地方,子类一定可以出现。
# 依赖倒转原则(DIP)
要依赖于抽象,不要依赖于实现。
要针对接口编程,不要针对实现编程。
> 从复用的角度来看,高层次(抽象层次)的模块是设计者应当复用的。
同样,最重要的宏观业务逻辑也应当是维护的重点,而不是相反。
# 组合、聚合复用原则(CARP)
要尽量使用组合、聚合,而不是继承关系达到利用的目的。
> "Is-A"是严格的分类学单方意义上的定义,意思是一个类是另一个类的“一种”。
而"Has-A"则不同,它表示某一个角色具有某一项责任。
> 只有当每一个S在任务情况下都是一种B的时候,才可以将S设计成B的子类。
如果两个类的关系是"Has-A"关系而不是"Is_A"关系,这两个类一定违反里氏替换原则。
只有两个类满足里氏替换原则,才有可能是"Is-A"关系。
# 接口隔离原则(ISP)
应当为客户端提供尽可能小的单独接口,而不要提供大的总接口。
接口隔离原则所限制的是通信的深度,也就是说,通信应该尽可能地窄。
> 一个接口相当于剧本中的一种角色,而些角色在一个舞台上由哪一个演员来演则相当于接口的实现。
因此,一个接口应当简单地代表一个角色,而不是多个角色。如果系统涉及到多个角色的话,
那么每一个角色都应当由一个特定的接口代表。(角色隔离原则)
# 迪米特法则(LoD)
一个软件实体应当尽可能少的与其他实体发生想到作用。
广义的迪米特法则要求尽可能的限制通信的宽度和深度。
> 朋友圈的确定:
- 当前对象本身(this)
- 以参数形式传入到当前对象方法中的对象
- 当前对象的实例变量直接引用的对象
- 当前对象的实例变量如果是一个聚集,那么聚集中的元素也都是朋友
- 当前对象所创建的对象
> 当读者学习设计模式时,要学会问一个问题:这个设计模式可能对什么样的变换开放,
以及它做到这一点所要付出的代价是什么。
> 如果可以动态地将一个构件移走,并以另一个构件取而代之,那么这种构件就是可插入构件。
接口是实现构件可插入性的关键。
> Java接口:这是一种Java语言中存在的结构,有特定的语法和结构。
接口:指的是一个类具有的方法的特征集合,是一种逻辑上的抽象。
> 抽象类与子类的关系实际上是模板方法模式的应用。
> 优先使用Java接口声明一个超类型。
> 一个设计师设计一个新的抽象类,一定是用来继承的。
而这一个声明倒过来,也是对的:具体类不是用来继承的。
只要有可能,不要从具体的类继承。
> 抽象类应当拥有尽可能多的共同代码,尽可能少的数据。
> 从“开-闭”原则中可以看出面向对象设计的重要原则是创建抽象化,并且从抽象化导出具体化。
具体化可以给出不同版本,每一个版本都给出不同的实现。
> 变量被声明时的类型叫做变量的静态类型,变量所引用的对象的真实类型叫做变量的实际类型。
> 一个软件系统可以看成是一个虚拟世界,设计师本人就是“驾驭”这个世界的“统治者”。
那么中国古代圣贤的智慧完全可以应用到软件系统及其设计中去。
设计总原则,其实原则依附它。
一个软件实体应当对扩展开放,对修改关闭。
> “对可变性的封装原则”讲的是找到一个系统的可变因素,将之封装起来。
考虑你允许什么发生改变而不让这一变化导致重新设计。
继承应当被看做是封装变化的方法,而不应当被认为是从一般的对象生成特殊的对象的方法。
实现开-闭原则原则的重要步骤就是抽象化。
# 里氏替换原则(LSP)
任何基类出现的地方,子类一定可以出现。
# 依赖倒转原则(DIP)
要依赖于抽象,不要依赖于实现。
要针对接口编程,不要针对实现编程。
> 从复用的角度来看,高层次(抽象层次)的模块是设计者应当复用的。
同样,最重要的宏观业务逻辑也应当是维护的重点,而不是相反。
# 组合、聚合复用原则(CARP)
要尽量使用组合、聚合,而不是继承关系达到利用的目的。
> "Is-A"是严格的分类学单方意义上的定义,意思是一个类是另一个类的“一种”。
而"Has-A"则不同,它表示某一个角色具有某一项责任。
> 只有当每一个S在任务情况下都是一种B的时候,才可以将S设计成B的子类。
如果两个类的关系是"Has-A"关系而不是"Is_A"关系,这两个类一定违反里氏替换原则。
只有两个类满足里氏替换原则,才有可能是"Is-A"关系。
# 接口隔离原则(ISP)
应当为客户端提供尽可能小的单独接口,而不要提供大的总接口。
接口隔离原则所限制的是通信的深度,也就是说,通信应该尽可能地窄。
> 一个接口相当于剧本中的一种角色,而些角色在一个舞台上由哪一个演员来演则相当于接口的实现。
因此,一个接口应当简单地代表一个角色,而不是多个角色。如果系统涉及到多个角色的话,
那么每一个角色都应当由一个特定的接口代表。(角色隔离原则)
# 迪米特法则(LoD)
一个软件实体应当尽可能少的与其他实体发生想到作用。
广义的迪米特法则要求尽可能的限制通信的宽度和深度。
> 朋友圈的确定:
- 当前对象本身(this)
- 以参数形式传入到当前对象方法中的对象
- 当前对象的实例变量直接引用的对象
- 当前对象的实例变量如果是一个聚集,那么聚集中的元素也都是朋友
- 当前对象所创建的对象
> 当读者学习设计模式时,要学会问一个问题:这个设计模式可能对什么样的变换开放,
以及它做到这一点所要付出的代价是什么。
> 如果可以动态地将一个构件移走,并以另一个构件取而代之,那么这种构件就是可插入构件。
接口是实现构件可插入性的关键。
> Java接口:这是一种Java语言中存在的结构,有特定的语法和结构。
接口:指的是一个类具有的方法的特征集合,是一种逻辑上的抽象。
> 抽象类与子类的关系实际上是模板方法模式的应用。
> 优先使用Java接口声明一个超类型。
> 一个设计师设计一个新的抽象类,一定是用来继承的。
而这一个声明倒过来,也是对的:具体类不是用来继承的。
只要有可能,不要从具体的类继承。
> 抽象类应当拥有尽可能多的共同代码,尽可能少的数据。
> 从“开-闭”原则中可以看出面向对象设计的重要原则是创建抽象化,并且从抽象化导出具体化。
具体化可以给出不同版本,每一个版本都给出不同的实现。
> 变量被声明时的类型叫做变量的静态类型,变量所引用的对象的真实类型叫做变量的实际类型。
> 一个软件系统可以看成是一个虚拟世界,设计师本人就是“驾驭”这个世界的“统治者”。
那么中国古代圣贤的智慧完全可以应用到软件系统及其设计中去。