1、单一职责原则(SRP):

1)、难点在于接口类职责的划分,如果划分得好,那么在以后对需求更改时时非常有利的。因为更改一个接口类,会对其实现类产生影响,职责划分得越清晰,那么所影响到实现类的范围就越小,修改成本就降低。单一原则作用于接口、类,同时也使用与方法。


2)、职责定义为:“改变的原因”,并且总结出一个类或者模块应该有且只有一个改变的原因。一个具体的例子就是,想象有一个用于编辑和打印报表的模块。这样的一个模块存在两个改变的原因。第一,报表的内容可以改变(编辑)。第二,报表的格式可以改变(打印)。这两方面会的改变因为完全不同的起因而发生:一个是本质的修改,一个是表面的修改。单一功能原则认为这两方面的问题事实上是两个分离的功能,因此他们应该分离在不同的类或者模块里。把有不同的改变原因的事物耦合在一起的设计是糟糕的。保持一个类专注于单一功能点上的一个重要的原因是,它会使得类更加的健壮。继续上面的例子,如果有一个对于报表编辑流程的修改,那么将存在极大的危险性,打印功能的代码会因此不工作,假使这两个功能存在于同一个类中的话。

2、里氏替换法则诞生的目的就是加强程序的健壮性,同时版本升级也可以做到非常好的兼容性,增加子类,原有的子类还可以继续运行。在我们项目实施中就是每个子类对应了不同的业务含义,使用父类作为参数,传递不同的子类完成不同的业务逻辑,非常完美!

3、接口隔离原则:

1)、第一种定义:Clients should not be forced to depend upon interfaces that they don't use. 

2)、第二种定义:The dependency of one class to another one should depend on the smallest possible interface。

3)、两种定义其实是在解释同一个意思:接口尽可能细化,不要建立臃肿庞大的接口,这里要同单一职责的区分开,单一职责强调的是职责的单一,对接口方法的多少没有要求,例如一个职责里可能包含10几个方法,把这10多个方法放在同一个接口中,并提供多个模块来访问,各个模块按照规定的权限来访问,在系统外通过文档约束不使用的方法不要访问,按照单一职责原则是允许的,而按照接口隔离原则则行不通。接口隔离原则要求提供专门的接口,提供多少个模块就应该提供多少个接口,而不是建立一个臃肿庞大的接口。这也可以映射到日常生活中,每件事情按照某种意义都可以对其进行分类划分从而优化(更好对其管理)。那什么才算设计出好的符合接口隔离原则的接口呢?拒绝盲目跟从,了解具体情况,详细剖析,最好的设计原则都是出自在了解的基础之上,没有一个统一的规定。


4、迪米特法则(LoD):Only talk to your immedate friends,也叫最少知识原则(Least Knowledge Principle,简称 LKP)

这一原则尽可能多使用private、protected,而尽可能少使用public,也就是尽量内敛。自己能解决的事情不要依赖别的类,尽可能不要和其他类扯上联系,否则到后边调整要花费更多时间处理更多事情。迪米特法则的核心观念就是类间解耦,弱耦合,只有弱耦合了以后,类的复用率才可以提高,其要求的结果就是产生了大量的中转或跳转类,类只能和朋友交流,朋友少了你业务跑不起来,朋友多了,你项目管理就复杂,大家在使用的时候做相互权衡吧。


5、开闭原则:Software entities like classes, modules and functions should be open for extension but closedfor modifications. 一个软件实体应该对扩展开放,对修改关闭,是所有设计原则的基础。其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。注意:开闭原则说的是对扩展开发,对修改关闭,并不是意味着不做任何修改,我们可以把变化归结为几个方面:

1)、逻辑变化:只变化一个逻辑,而不涉及到其他模块,比如原有的一个算法是 a*b+c,现在需要修改为a*b*c,可以通过修改原有的类中的方法方式来完成,前提条件是所有依赖或关联类都按照相同的逻辑处理。

2)、子模块变化:一个模块变化,会对其他的模块产生影响,特别是一个低层次的模块变化必然引起高层模块的变化,因此在通过扩展完成变化时,高层次的模块修改是必然的,刚刚的书籍打折处理就是类似的处理模块,该部分的变化甚至会引起界面的变化。

3)、可视图变化:可见视图是提供给客户使用的界面,如 jsp 程序,swing 界面等,该部分的变化一般会引起连锁反应(特别是在国内做项目,做欧美的外包项目一般不会影响太大),如果仅仅是界面上按钮、文字的重新排布倒是简单,最司空见惯的是业务耦合变化,什么意思呢?一个展示数据的列表,按照原有的需求是六列,突然有一天要增加一列,而且这一列要跨度 N 张表,处理 M 个逻辑才能展现出来,这样的变化是比较恐怖的,但是我们还是可以通过扩展来完成变化,这就依赖我们原有的设计是否灵活。新业务需求到来时,我们要保持了历史的纯洁性。放弃修改历史的想法吧,一个项目的基本路径应该是这样的项目开发、重构、测试、投产、运维,其中的重构可以对原有的设计和代码进行修改,运维尽量减少对原有代码的修改,保持历史代码的纯洁性,提高系统得到稳定性。