目录
1.单一职责原则
2.里氏替换原则
3.依赖倒置原则
4.接口隔离原则
5.迪米特法则
6.开闭原则
以下专业术语来自韩敬海主编《设计模式(Java版)》一书,每一种原则都会写上我自己的理解,如有不妥之处,欢迎各位指出,也可以把你的理解分享出来,大家共同学习
单一职责原则
单一职责原则的定义:
一个类,应当只有一个引起它变化的原因;即一个类应该只有一个职责。
我举一个通俗例子来说下我的理解,拿订单类来说,平时大家网购的时候也应该知道,订单包含了用户信息(订单是谁的),订单有什么商品,这些是订单最基本的,也是必不可少的,但是下单的时候可以用到优惠券,那这个优惠券信息是否应该放在订单类呢?显然是不可以的,因为优惠券并不是订单必须的属性,我下单的时候当然可以选择使用优惠券也可以不使用优惠券,如果我将优惠券金额存在订单类有什么后果呢?有人说优惠券金额存在订单类不是很直观吗,查起来也很方便。
查起来是很方便,但是如果用户更换了优惠券呢,这个时候还得去修改订单表(实体类一般都会映射到表)中的优惠券金额,那么这就是优惠券引起的订单类的变化,这里就违背了只有一个引起它变化的原因
所以,订单信息中不应该存在优惠券信息,专业术语就是订单和优惠券耦合了
唯有单一,才能保证对象的细粒度。对象的高内聚与细粒度有利于对象的重用
单一职责原则的优点有一下几个方面:
1.降低类的复杂性;
一个类只有一个职责,也就是只有最少(最基本)的信息,当然是最简单的,所以降低了类的复杂性
2.提高类的可读性;
3.提高代码的可维护性和复用性;
4.降低因变更引起的风险。
总结:一个类只应该有他最基本(最必需)的信息
里氏替换原则
里氏替换原则的定义:
如果对一个类型为S的对象o1,都有类型为T的对象o2,使得以S定义的所有程序P在所有的对象o1都替换成o2时,程序P的行为没有发生变化,那么类型T是类型S的子类型。
看着有点绕,没关系,接着再看一段
里氏替换要求凡是使用基类的地方,子类一定适用,因此子类必须具备基类的全部接口。
这句话就比较好理解了,里氏替换讲的就是继承的规范,替换
就是子类替换父类,父类出现的地方一定可以用子类替换,也就是说父类有的子类一定有
例如Animal是Dog的父类,在实例化Dog类的时候应该这么写Animal dog = new Dog();
而不是这么写Dog dog = new Dog();
为什么呢?因为Animal是Dog的抽象,是代表一类事物而不仅仅是一个Dog,范围更广,所以适用性更好。
这个应该在我们平常写码中非常普遍了,只不过可能不知道叫这个设计原则吧
依赖倒置原则
依赖倒置原则的定义:
高层模块不应该依赖底层模块,两者都依赖其抽象;抽象不依赖细节;细节应该依赖于抽象。
何为依赖倒置,最开始的依赖是怎样?
传统的过程性系统的设计办法倾向于高层次的模块依赖于低层次的模块;抽象层次依赖于具体层次,“倒置”原则将这个错误的依赖关系倒置了过来
还是Animal和Dog的例子,比如public void test(Dog dog)这个方法的参数传的是Dog,那么这个方法就依赖了Dog这一个具体的类,这就是依赖了细节,所以test方法这里应该传参Animal,Animal为参数的话就扩大了test方法的参数范围,增强了适用性(复用性),这个我们平时代码中也用的比较多
也就是常说的面向接口编程
综上,依赖倒置原则、里氏替换原则的关键字是:高可复用,低耦合
接口隔离原则
接口隔离原则定义:
客户端不应该依赖它不需要的接口;类间的依赖关系应该建立在最小的接口上。
再看另一个解释
一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。因此使用多个专门的接口比使用单一的总接口要好。
不知道大家有没有觉得接口隔离原则很像单一职责原则,也就是说接口中的内容只需要是最基本、最必需的即可,就好比Animal接口中定义了fly方法就不妥,因为Dog不能飞,所以这个方法就是多余的(对于Dog来说),那么就违背了接口隔离原则
接口隔离原则希望一个接口要保证它是最小的接口
迪米特法则
迪米特法则定义:
迪米特法则又叫最少知识原则,意思是一个对象应当对其他对象尽可能少的了解。
说实话这个我没太理解,给我的第一印象就是封装,等后面有体会了再来补充下,再看下另一段解释
迪米特法则的核心观念就是类之间的解耦、弱耦合,只有弱耦合了以后,类的复用率才可以提高
就又回到了,高复用、低耦合
的观点上了
开闭原则
开闭原则的定义:
一个软件实体应当对扩展开放,对修改关闭。
由这个定义我又想到了面向接口编程
,何为接口?比如List接口
这么多实现类都实现了List接口,我想一开始也不会有这么多实现类的吧,肯定是后面需要某些具体的功能,然后就去扩展一个xxxList出来,这就是对扩展开放
那何为对修改关闭呢?加入我改了List接口中的int size();
size改成了xxx,那还不炸了,实现了List的类就都得改,又或者我在List中新增了一个方法yyy,那所有的实现类也必须要去实现这个方法,不过java8中出了default
关键字规避了这个问题
其实这六大设计原则并不是孤立的,也不是绝对正确的,世界上本来就没有绝对的对和绝对的错,万事万物都是相对的,大家写码的时候尽量去遵循这六大设计原则就行了,毕竟是前人总结出来的经验!
以上就是我对六大设计原则的总结,如有不妥欢迎指出,也希望能帮到大家