1,OCP(Open-Close Principle)开闭原则
Software entities should be open for extension,but closed for modification,(在设计一个模块的时候,应当使这个模块可以在不被修改的前提下扩展)。
对扩展开放open,对修改关闭close。
如何实现?1,抽象化是关键,2对可变性的封装原则(Principle of Encapsulation of Variation EVP)。
用我自己的话来说,在我们设计模块的时候,要将其他“类似”的类,提取出来共同的代码,就是所谓的“抽象”。而对于哪些代码放在抽象类里面去,就是存在可变性的地方.对于这点,我还没有体会到。
典型容易理解的列子,工厂模式。当需要新增加一个类的时候,直接继承product接口就可以了。
2,Liskov Subsitution Principle(LSP)里氏代换原则
就是子类可以代替父类出现的任何地方,在抽象的时候,重要的要理解的一个地方两个类之间是什么关系,是“has-A”?还是“Is-a”的关系。在“has-a”的关系中,两个类存在的是依赖的关系(在类A里面存在类B的的变量);在“Is-a”的关系中,可以提取这两个类的“共同代码”放在抽象类C中,然后A,B继承与C,这也是一种重构。
3,Dependency Inversion Principle(DIP)依赖倒转原则
就是在我们编程的时候方法的参数类型,变量,对于其他具体类的依赖,我们尽量的使用抽象类。
就是说尽量依赖于抽象,而不是依赖于实现。
在书中两种表述:
(1),Abstraction should not depend on details.details should depend on abstraction. (抽象不应当依赖于细节,细节应当依赖于抽象)。Abstraction就像是建筑物的基础,而其实现类就是在基础上面一层一层的往上面走。你拆掉最上面那层,和拿走最下面的基础,有什么不同了,这就是差异了。所以Abstraction是要相当的稳定,是维护的重点。也正是因为稳定,所以我们尽量的依赖于Abstraction,既是稳定系统,也是灵活系统。
(2),Program to an Interface,not an implementation(要针对接口编程,不要针对实现编程)
应当使用java接口和抽象java类进行变量的类型声明,参数的类型声明,方法返回值的类型和数据类型的转换。
在这里我就有一个问题了。
List l=new Vector();而不要使用 Vector l=new Vector();我就有疑问 如果我一个类B 继承于类A,B有一些A不存在的方法,而我的方法中我得使用B,这里那就菜了。
所以看到这句话了。保证做到这点,一个具体的类应当只实现Java接口,和抽象java类中声明过的方法,而不应当给出多余的方法。
依赖倒装原则是很难实现的,在这些原则中,因为从上面也可以看到。还是使用了Vector类这个具体的类,还是对具体的类有依赖,所以,对于依赖倒装的创建new Vector(),有一个专门的模式,工厂模式,不过只是把违反这个原则的地方压缩到一个类里面。
4,Interface Segregation Principle(ISP)接口隔离原则
限制一个实体对另一个实体通信时候的宽度。
就是一个类对另外一个类依赖的时候,应当是建立在最小的接口上面。对于接口隔离原则来说,有两种接口,一种是真正意义上面的“java 接口”Interface;另外一种是指一个类的方法的集合。对于这来两种有,两个接口隔离的原则,对于一个类里面的方法的集合的接口隔离,我们称作是“角色隔离原则”;另外一种叫做“定制服务”。
定制服务,就是一个类,我给你这个客户端一些方法,我放在一个java接口(Interface)里面。给另外一个客户端另外一些方法,放在另外一个接口(Interface).
角色隔离原则,是指客户端要多个不同的类的方法,我们就搞几个不同类别的接口(Interface),在书中,这么比喻的,就相当于电影剧本里面的人物,我们找人来演,这个人就是具体的类。这就叫做角色隔离原则。
5,Composition/Aggregation Reuse Principle(CARP)组合/聚合复用原则
就是说要尽量的使用合成和聚合,而不是继承关系达到复用的目的。
其实这里最终要的地方就是区分“has-a”和“is-a”的区别。相对于合成和聚合,继承的缺点在于:父类的方法全部暴露给子类。父类如果发生变化,子类也得发生变化。聚合的复用的时候就对另外的类依赖的比较的少。。
6,Least Knowledge Principle(LKP)最少知识原则,又称为“Law of Demeter”迪米特原则。
和ISP接口隔离原则一样,限制类与类之间的通信。ISP限制的是宽度,而LoD迪米特原则限制的是通信的广度和深度。
LoD在广度上面,尽量减少远距离类的关联,而使用与自己有关的类,并且也与远距离类有关的类。
可是这种做法有一点麻烦。多个远距离类产生关联的时候,不怎么容易处理,所以增加一个远距离类的抽象类。所有的远距离类都是通过抽象类的形式来访问。
在深度上面,控制权限是最重要的,对于类,一个是default 和public,尽量最小权限;对于成员,private,default,protected,public。往上面走,权限越小,依赖的耦合就越小。
有几种描述:
(a)Only talk to your immediate friends.
(b)Don't talk to strangers.
设计模式“facade”,"调停者模式"。在这里是IoD的典型表现。