学习笔记-Java设计原则
Java设计原则&&模式学习笔记
说明
近期扫地生决定整合一下年初学习的设计模式,一来用于复习巩固,二来也希望可以把自己的整合与有需要的同学共勉。
扫地生在学习的过程中主要参考的是公众号“一角钱技术”的相关推文,同时也参考了下列几篇文章。对这些作者扫地生表示衷心的感谢。
1、Java设计原则(6大原则)
1.1 单一职责原则(Single responsibility principle,缩写为:SRP)
说明:一个类或者模块只负责完成一个职责,通俗的说法就是一个模块、类、方法不要承担过多的任务。
原则上来说,设计一个类的时候不应该设计成大而全的类,要设计粒度小,功能单一的类,如果一个类两个或者两个以上的不相干的功能,就说明它未被了单一职责原则,应该将它拆分成多个功能单一,力度更细的类。
实际软件开发工作中,不必严格遵循原则,可以设计一个粗粒度的类,随着业务的发展,再进行重构。
实际开发中可以按照以下参考意见,进行代码的重构或设计:
-
类依赖过多其他类时、代码直接的依赖关系过于复杂时、不符合高内聚低耦合的设计思想时,就可以考虑对代码进行拆分。
-
类的名称和实际的功能关系不大或者没有任何关联性的时候,可以更加细粒度地拆分,把无关的功能独立出去。
-
类的代码函数过多影响可读性和代码维护时可以对代码进行方法级别的拆分。
1.2 开闭原则(Open-Closed principle,缩写为:OCP)
说明:软件实体(模块、类、方法等)应该“对扩展开放、对修改关闭”。就是说添加一个功能应该是在已有代码基础上进行扩展,而不是修改已有代码。
开闭原则的目的是为了代码的可扩展,并且避免了对现有代码的修改给软件带来的风险,可扩展的前提是需要了解到未来的扩展点,那实际软件开发中如何找到所有扩展点?可以从以下几个方面进行分析:
- 如果是业务驱动的系统,需要在充分了解业务需求的前提下,才能找到对应的扩展点。如果不确定因素过多,需求变化过快,则可以对于一些比较确定的,短期内就可能会扩展,通过设计扩展点,能明天提升代码稳定性和开发效率的地方进行设计。
- 如果是通用型技术开发,比如开发通用的框架,组件,类库,需要考虑该技术框架将如何被用户使用,考虑功能的升级需要预留的额扩展点以及版本之间的兼容问题。
- 即使对系统的业务或者技术框架有足够的了解,也不一定要设计所有的扩展点,为未来可能发生变化的每个地方都预留扩展点,也会给系统带来极大的复杂度,实现起来工作量也不可小觑,需要综合开发成本,影响范围,实际收益(时间和人力)等因素进行考虑。
1.3 里氏替换原则(lisko substitution principle,缩写为:LSP)
说明:子类对象能够替换程序中父类对象出现的任何地方,并且保证原来程序逻辑行为不变及正确性不被破坏。
可以利用面向对象编程的多态性来实现,多态性和里氏替换原则有些类似,但他们的关注点不一样,多态是面向对象编程的特性,而里氏替换原则是一种设计原则,用来指导继承关系中子类该如何设计,子类的设计要确保在替换父类的时候,不改变原有程序的逻辑以及不破坏原有程序的正确性。
具体实现方式可以理解为:子类在设计的时候,要遵循父类的行为约定。父类定义了方法的行为,子类可以改变方法的内部实现逻辑,但不能改变方法原有的行为约定,如:接口/方法声明要实现的功能,对参数值,返回值,异常的约定,甚至包括注释中所列举的任何特殊说明。
1. 4 接口隔离原则(Interface segregation principle,缩写为:LSP)
说明:客户端不应该强迫依赖它不需要的接口。
接口隔离原则的实现可以从以下几个方面分析:
- 对于接口来说,如果某个接口承担了与它无关的接口定义,则说该接口违反了接口隔离原则,可以把无关的接口剥离出去,对胖而杂的接口瘦身。
- 对于共通的功能来说,应该细分功能点,按需添加,而不是定义一个大而全的接口,让子类被迫去实现。
1.5 依赖倒置原则(Dependency inversion principle,缩写为:DIP)
说明:高层模块不依赖底层模块,高层模块和底层模块应该通过抽象来互相依赖,除此之外,抽象不要依赖具体实现细节,具体实现细节依赖抽象。
高层模块从代码角度来看就是调用者,底层模块就是被调用者。即调用者不要依赖于具体的实现,而应该依赖于抽象,如Spring框架中的各种Aware接口,框架依赖于Aware接口给予具体的实现增加功能,具体是通过实现接口来获取功能,而具体的实现与框架之间并没有直接耦合。
1. 6 迪米特法则(最少知道原则,Demeter Principle,缩写为:DP)
说明:一个对象应该对其他对象保持最少的了解。尽量降低类与类之间的耦合
2、Java设计模式概述
设计模式(Design pattern)是一套被反复使用,多数人知晓的,经过分类目的,代码设计经验总结。使用设计模式是为了可重用代码,让代码更容易被他人理解、保证代码可靠性。设计模式对于人和系统来说都是双赢的,设计模式使代码编制真正工程化,设计模式可以看做是软件工程的基石。项目中合理的应用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每一个模式描述了一个我们周围不断重复发生的问题,以及该问题的核心解决方案。
模式:在某些场景下,针对某类问题的某种通用的解决方案。
场景:项目所在的环境
问题:约束条件,项目目标
解决方案:通用,可复用的设计,解决约束达到目标
2.1 Java设计模式的三个分类
创建型模式:对象实例化模式,创建型模式用于解耦对象的实例化过程。
结构型模式:把类或对象结合在一起形成一个更大的结构。
行为模式:类和对象如何交互,及划分责任和算法。