第二章 面向对象设计原则
2.1面向对象设计原则概述
设计原则名称 | 定义 |
---|---|
单一设计原则(Single Responsibility Principle) | 一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中 |
开闭原则(Open-Closed Principle) | 软件实体应当对扩展开放,对修改关闭 |
里氏替换原则(Liskov Substitution Principel) | 所有引用基类的地方必须能透明地使用其子类的对象 |
依赖倒转原则(Dependence Inversion Principle) | 高层模块不应该依赖底层模块,它们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象 |
接口隔离原则(Interface Segregation Principle) | 客户端不应该依赖于那些它不需要的接口 |
合成复用原则(Composite Reuse Principle) | 优先使用对象组合,而不是通过继承来达到复用的目的 |
迪米特法则(Law of Demeter) | 每一个软件单位对其他单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位 |
2.2单一职责原则
单一职责原则定义:一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。
另外一种定义:就一个类而言,应该仅有一个引起它变化的原因。
1.分析现有功能
- init() 的作用是在登录时,对登录界面进行初始化
- display() 负责显示登录界面
- validate()对当前界面用户输入的信息进行语法合法性检验,这个是语法验证,比如说用户的密码输入了没有,是否为空;年龄是否是负数…而不是对用户进行合法性验证
- getConnection() ,findUser(),用户的信息保存在数据库中,要进行用户信息的验证,要连接数据库,并且在数据库中寻找输入的用户。
- mian() ,是整个系统的入口
2.存在问题
根据单一职责原则,一个应该只有一个职责。现在的登录类大体来讲至少有3种职责。
(1)前面三个方法是合理的,都是与登录界面有关系的。初始化登录界面,展示登录界面,对界面输入的信息进行语法性检验。
(2)但是 getConnection() 和 findUser()
这两个方法是与业务逻辑有关系的,他们是用来判断一个用户是否是合法的。(3)mian() 方法与登录类没有关系,它是整个系统的入口。只不过是恰好存在系统入口是先进入登录界面的情况
单一职责另外一种定义:就一个类而言,应该仅有一个引起它变化的原因。从这个角度出发,登录类承担的职责过多,有多个引起它发生变化的原因。
比如说,界面发生变化,要修改 display() ;数据库里面的用户发生变化要修改 getConnection();如果入口要增加一些触发工作,要修改 main()…
3.使用单一职责原则进行重构
使用这个原则的方法就是进行拆分,把一个登录类拆分为四个类,如下图
(1)MainClass: 里有一个 main(),负责系统的入口
(2)LoginForm :是一个界面视图,界面表单。里面有界面的初始化,界面展示,语法检验方法。
(3)UserDAO:是数据访问对象,是用于访问用户对象的,与用户对象打交道的,里面有 findUser()
(4)DBUtil:数据库连接工具,负责与 数据库进行连接
拆分了之后,有变化就修改对应的类就可以。
原文参考链接:https://blog.csdn.net/qq_43403759/article/details/117417230
2.3 开闭原则
开闭原则:软件实体应当对扩展开放,对修改关闭
在开闭原则的定义中,软件实体可以指一个软件模块、一个由多个类组成的局部结构或一个独立的类。
抽象化是开闭原则的关键。抽象化就是将一个类(实体)里面或者多个类里面公共的东西抽取出来,抽象的好处就是稳定的、可靠的、不容易发生改变的。
开闭原则还可以通过一个更加具体的“对可变性封装原则”来描述,对可变性封装原则要求找到系统的可变因素并将其封装起来。