设计模式的原则其实大都是为了对象间的松耦合设计而产生的,它强调对接口编程。通过接口定义规则,再通过类去实现,并将其变化独立出来,便于扩展和复用。
开闭原则(Open Close Principle),是设计模式的核心,其实开闭原则算是其他几个原则的一个综合体现。它说的是对象(类,模块,函数等)对扩展开放(对提供方来说可以扩展新功能),对修改关闭(对使用者来说不修改代码),用抽象构建框架(使用抽象类或者接口搭建框架指定规则),用实现扩展细节(用类去继承实现抽象类或接口,然后扩展具体的代码)。
可扩展,不可修改。其实下面的几种原则在一定程度上就是为了实现开闭的原则。
简单来说就是我们的软件如果要变化的时候,我们是通过制定好的框架(接口和抽象类)来去扩展实体行为(增加新的实现类,扩展新的方法),而非修改已经完成的代码(不修改以前已经完成的代码)。
程序中,就一个类而言,应该仅有一个引起他变化的原因,一个类只负责一项职责。比如:在对应数据库时通常一张表对应一个实体类,一个类对应一个dao类,一个controller对应一种功能。
但是有些时候类过于简单的时候,在类级别使用单一原则,会导致成本提高,这时候也可以使用方法上遵循单一原则(一个类内部有多个不同职责的方法)(在类比较简单时使用)。
里式替换是建立在继承的基础上。子类可以修改父类已经实现好的方法,但是如果对其进行任意的修改,会造成整个继承体系的破坏。所以说继承有优点也有缺点。
正是因为继承的一系列缺点,所以才引用了里式替换原则去解决。
里式替换原则:任何基类出现的地方,其子类也一定可以出现。
比如:如果定义一个Animal(动物类),其子类Dog、Fish、Bird都继承这个Animal类,那么我们不管再怎么去区分它们,不论是天上飞的还是地上跑的,这三者它们至少都是动物。==不管子类的功能如何扩展,都至少都是一个父类。==在编程中,把父类都替换成它的子类,程序的行为没有发生变化。
而里式替换的根本就是:子类可以扩展父类的功能,但是不能改变父类原有的功能,只有这样这样子类才能去替换父类。也正是这种替换父类模块无需修改就能实现扩展。
里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
俗称面向接口编程,依赖于抽象(接口、抽象类)不依赖于具体(实现类)。简单来说就是:使用接口或抽象类制定好规范,不涉及具体操作,把细节交给下面的实现类去做。依赖倒转原则是开闭原则的基础。
我们创建一个类为猫、一个类为狗,再创建一个人的类。如果要表示一个人养了狗或养了猫,那一个方法是不能表示的,需要去Person里更改传入的代码,或者重写方法,但是当我们再创建其他动物的对象时,Person中的方法就要增加一个,这样显然是不合理的,那么怎么解决呢?

对于上面的问题,就是运用依赖倒转原则,建立一个接口用接口来管理下面的实现类,比如我们创建一个动物的接口,让猫和狗去实现这个接口,这样在Person中直接通过传入接口就可以管理猫和狗甚至更多的实现了动物接口的类

我们也可以用set方法去注入一个对象

接口隔离原则(Interface Segregation Principle):客户端不应依赖它不需要的接口,类间的依赖关系应该建立在最小的接口上(大接口拆分为小接口)。使用多个隔离的小接口,比使用单个大的接口要好。
比如一个才艺接口,内部有四个方法(唱歌、跳舞、蓝球、游戏),两个类:男孩(玩蓝球、游戏)和女孩(唱歌、跳舞),这两个类都实现才艺接口势必有两个方法是空的。

这就是接口臃肿的表现,如果将这个设计修改为符合接口隔离原则,就必须对接口进行拆分。

迪米特法则(Demeter Principle)又叫最少知道法则,一个类对自己所依赖的类知道的越少越好。实际上就是强调类之间的松耦合关系。松耦合越弱就越容易实现复用,同时在修改时造成的影响就越小。
当类与类之间的关系越密切,它的耦合性就越大,所以类无论是多复杂,都尽量降低成员的访问权限。比方说:一个类的基本属性,我们基本都会用private修饰,然后提供set和get方法进行修改,但是我们也仅仅是调用方法,传递参数,具体怎么修改只有类自己才知道。
简单来说就是类只和自己的直接朋友通信,使的模块之间相对独立。两个对象之间的耦合关系就是朋友关系,耦合的方式有:依赖、关联、组合、聚合等,但是其中有直接朋友和非直接朋友的区别。
这种作法就是为了减少耦合。这种作法的好处,就比如电脑,现在的高配电脑都是组装机,每次更新,买CPU和GPU等零部件更换即可,就是因为现在的电脑部件都是高内聚,低耦合的。以前的电脑各个部件之间互相缠绕,互相耦合,想达到自己换零部件的需求时很难很难的。
合成复用原则(Composite Reuse Principle):尽量使用合成/聚合的方式,而不是使用继承。它可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少。
我们思考一下,有两个类A和B,我们想在B中使用A类的方法时,有几种作法?除了第一种外另外三种都可以使用,第一种的依赖关系太强所以不推荐。