封装,抽象,继承,多态
继承复用会破坏系统的封装性,因为继承会将类的实现细节暴露给子类,由于基类的某些内部细节对子类来说是可见的,因此这种复用又称为“白箱”复用,如果基类发生改变,那么子类的实现也不得不发生改变。
组合/聚合复用可以调用已有对象的功能,但是成员对象的内部实现细节对新对象是不可见的,因此这种复用又称为“黑箱”复用,对比继承复用而言,其耦合度更低,成员对象的变化对新对象的影响不大,而且合成复用可以在运行时动态进行,新对象可以动态的引用与成员对象类型相同的其他对象。
任何一个软件模块都应该有且仅有一个被修改的原因。
每个模块都应该只做一件事。
单一职责原则主要讨论的是函数和类之间的关系——但是它在两个讨论层面上会以不同的形式出现。在组件层面,可以将其称为共同闭包原则,在软件架构层面,它则是用于奠定架构边界的变更轴心。
设计良好的计算机软件应该易于扩展,同时抗拒修改。
主要目标:让系统易于扩展,同时限制其每次被修改所影响的范围。
实现方式:通过将系统划分为一系列组件,并且将这些组件间的依赖关系按层次结构进行组织,使得高层组件不会因为底层组件被修改而受到影响。
抽象是开闭原则的关键
如果需要修改系统的行为,无须对抽象层进行改动,只需要增加新的具体实现来实现新的业务功能即可,实现在不修改已有代码的基础上扩展系统的功能。
现实中可能会对具体的实现有一定的修改。
子类对象可以在程式中代替其基类超对象。
定义接口时要尽可能提供职责唯一的接口,而不是大而全的接口,因为实现一个接口就得实现该接口的所有方法。大而全的接口不利于系统的维护与扩展。但同时也要控制接口粒度不能太细,否则可能会导致“接口爆炸”。
依赖抽象,不要依赖具体实现。
与 "针对接口编程,不针对实现" 编程的区别:
依赖倒置更强调 抽象,不能让高层组件依赖低层组件,而且不管高层或底层组件,都应该依赖于抽象。
一般情况下实现是底层组件,抽象是高层组件。这种原则中会出现 底层组件依赖高层的抽象,高层组件现在也依赖相同的抽象。
源代码的依赖方向永远是控制流方向的反转——这就是DIP被称为依赖反转的原因。
软件复用的最小粒度应等同于其发布的最小粒度。
如果要复用某个软件组件的话,一般就必须要求该组件的开发由某种发布流程来驱动,并且由明确的发布版本号。
从软件设计和架构设计的角度看,REP原则就是指组件中的类与模块必须是彼此紧密相连的。一个组件不能由一组毫无关联的类和模块组成,它们之间应该有一个共同的主题或大方向。
例如:不同SpringBoot版本中对其依赖版本号的管理。
我们应该将那些会同时修改,并且为相同目的而修改的类放到同一个组件中,
而将不会同时修改,并且不会为了相同目的而修改的那些类放到不同的组件中。
这是SRP原则在组件层面的再度阐述。
CCP与SRP原则都可以概括为:将由于相同原因而修改,并且需要同时修改的东西放在一起。
不要强迫一个组件的用户依赖他们不需要的东西。
CRP原则实际上是ISP原则的一个普适版。ISP原则是建议我们不要依赖带有不需要的函数的类,而CRP原则则是建议我们不要依赖带有不需要的类的组件。
只和朋友交谈。
每个软件单位对其他单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。
迪米特原则要求一个软件实体应该尽可能少地与其他实体发生相互作用,从而降低系统的耦合度,使类与类之间保持松散的耦合关系。
高层组件对待底层组件的方式是 别调用我们,我们会调用你
好莱坞原则强调高层对低层的主动作用,即低层应该只管好自己的工作(具体实现),而高层自有它自己的工作(这就是管理低层的逻辑们)。
IOC的原理就是基于好莱坞原则