什么是设计模式
随着编程的发展,程序员们发现再解决一些普遍的问题的时候,所使用的解决方案是大体相同的。这些解决方法是众多程序员经过长时间的实践和试错最终总结出来了。所有就有人将它们总结起来形成了设计模式。设计模式出现的意义是为了重用代码,让代码更容易被人理解、保证了代码的可靠性。如果我们能熟练的掌握这些设计模式,我们就能完美的解决开发时的大多数问题。让代码更加优雅。这就是我们要了解、学习设计模式的原因。
优点:
- 当设计模式中的一些专业名词被大家了解,则当开发人员在讨论项目时交流更加高效,更好理解对方的想法。
- 提供了经过验证的解决方案,提高了软件的可维护性(在遇到错误时可以从网上寻求解决方案)、可复用行和灵活性。
- 促进了代码的重用,避免的重复的设计和实现。
- 通过遵循设计模式,可以减少开发过程中遇到的错误和问题,提高代码质量。
但在学习具体的设计模式之前,我们要先了解学习设计模式的六大设计原则。
1、单一职责原则
单个类职责统一,不要将所有功能都放在一个类上去实现。类中方法一个方法只做一件事。所谓的职责单一其实是指当前类所承担的业务是最小颗粒,而完整的业务是这些颗粒组合、互相调用实现的,我们要将职责划分清楚。对于具体如何划分要根据业务需求和个人经验能力来决定。它有一些基础的原则:
- 两个功能完全不同的方法不应该写再同一个类当中。
- 一个类应该是一组相关性很高的数据和方法的包装。
举例:再购买一个东西,它有原价,和各种的优惠政策,最后得到了现价。我们不能把优惠策略方法和原价这些方法写到一个类当中,而是将其分开类写,当优惠政策改变时只需要开动优惠政策那的方法。只需要原价传入优惠的方法即可。
2、开闭原则
类的设计对扩展开放,对修改关闭。增加功能时尽可能的使用扩展,而不是使用修改原有的代码达到目的。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。
例:对于一个商品类我们有一个获取价格(getPrice())的方法,但当它需要打折时,我们想到的是增加一个子类,重写它的getPrice()方法。这时打折用其子类就行了,更加灵活。
3、里氏替换原则
所有引用基类的地方,必须能使用其子类进行替换。
在面向对象的继承关系当中,只要父类出现的地方子类就可以出现,将其替换为子类不会出现任何错误或异常。使用者可能根本不需要知道是父类还是子类,但反过来就不行了,有子类出现的地方,父类未必能适应。子类可以替换父类,且不是功能发生改变。
规范:
- 子类必须完全实现父类的方法。
- 子类可以有自己的个性(重写)。
- 覆盖或者实现父类方法的时候,输入参数可以被放大(如:父类参数为HashMap,子类参数可以变为Map)
- 方法返回值子类要比父类更加严格,(如:父类:Map,子类返回可以为HashMap)。
4、接口隔离原则
使用多个隔离接口比使用单个接口要好。也就是降低类之间的耦合度。由此可见其实设计模式就是从大型软件建构出发、便于升级和维护的软件设计思想,它强调降低依赖、降低耦合。
具体来说就是接口粒度尽量小,对于相同职责的接口方法进行分组,尽量一个接口只给一个子模块或者业务使用,但不要太过于细化,不然结构会过于复杂。
规范:
- 接口尽量小
- 接口要高内聚:提高接口、类、模块的处理能力,减少对外交互,要求在接口中尽量少公布public方法,减少对外承诺也利于降低成本
- 定制服务,针对不同的用户提供不同的服务,只提供访问者需要的方法。如给不同权限的用户提供不同的接口操作。
5、依赖倒置原则
上层模块不应该依赖下层模块,而是应该通过接口交互。不可分割的原子逻辑就是下层模块,而下层模块组装起来的就是上层模块,这样的话当上层有变化的时候,下层不会有感知修改。
这就是面向接口编程,是面向对象设计的精髓之一,可以减少类之间的耦合度,提高系统的稳定性,减低并行开发引起的风险。
规范:
- 模块之间依赖通过接口或抽象类发生,实现类之间不能直接依赖
- 接口和抽象类不依赖实现类
- 实现类依赖于接口或抽象类
6、迪米特原则(又称:最少知道原则)
顾名思义,就是一个实体类应当对其他对象要尽量少了解,尽量的与其他实体类之间发生相互作用。对类之间要低耦合。使系统功能模块相对独立。
例(结合实例):
- 领导下发任务,只需和组长讲明需求即可,与组员说明的工作由组长来完成。
- 组员之间工资信息不能互相透露,不然修改一个人的工资,对其他组员工作积极性有影响,都要调动。