面向对象设计原则

1、开闭原则

  • 开闭原则理解:

    简单说就是一个软件实体支持扩展,不支持修改。就是在不改变源码的基础上,扩展其它的功能。

    其实笔者认为,开闭原则无非就是想表达这样一层意思用抽象构建框架,用实现扩展细节。因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节,我们用从抽象派生的实现类来进行扩展,当软件需要发生变化时,我们只需要根据需求重新派生一个实现类来扩展就可以了。当然前提是我们的抽象要合理,要对需求的变更有前瞻性和预见性才行。

  • 开闭原则实现:

    开闭原则主要实现于接口或抽象类,接口和抽象类只提供功能(即不可修改),功能的具体扩展需要定义实现类去实现(即可扩展)。

  • 开闭功能的好处:

    通过扩展已有软件系统,可提供新的行为,以满足对软件的新需求,提高了软件系统的适应性和灵活性,特别是最重要的抽象层模块不能再修改,提高了软件系统的一定的稳定性和延续性,这样的设计同时也满足了可复用性与可维护性;

2、单一职责

  • 系统中的每一个类都应该只有一个职责,而所有类所关注的就是自身职责的完成。

    一个类(或者大到模块,小到方法)承担的职责越多,它被复用的可能性越小。而且如果一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作。

  • 为什么要遵守单一职责原则?

    1、提高类的可维护性和可读写性

    一个类的职责少了,复杂度降低了,代码就少了,可读性也就好了,可维护性自然就高了。

    2、提高系统的可维护性

    系统是由类组成的,每个类的可维护性高,相对来讲整个系统的可维护性就高。当然,前提是系统的架构没有问题。

    3、降低变更的风险

    一个类的职责越多,变更的可能性就更大,变更带来的风险也就越大。

  • 如何遵守单一职责原则

    合理的职责分解,相同的职责放到一起,不同的职责分解到不同的接口和实现中去

3、里氏替换原则

里氏代换原则的定义是——子类型必须能够替换掉他们的父类型。

如果一个软件实体使用的是一个父类的话,那么就肯定适用其子类,并且该软件实体察觉不到父类对象和子类对象的区别。

举个例子,有个很厉害的老木匠,周边的邻居都找他做家具,老木匠还有个大徒弟,不但学全了老木匠的本事还青出于蓝而胜于蓝。后来老木匠干不动了,所以每次有人找上门来都是老木匠接活儿,大徒弟去做家具,而对做家具的人来说,他们并不关心具体谁做的,只要能拿到家具就好。

只有在满足了里氏替换原则之后,也就是子类可以代替父类出现,并且不影响程序的功能时,父类才能真正得到复用,并且子类可以在父类的基础上添加新的行为,面向对象思想中,父类和子类的继承关系是抽象化的具体实现。

4、依赖倒转原则

定义如下:

高层模块不应该依赖低层模块,它们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象。

另一种表述为:要针对接口编程,不要针对实现编程。

 1  public class Driver {
2 //司机的主要职责就是驾驶汽车
3 public void drive(ICar car){
4 car.run();
5 }
6 }
7 //将汽车模块抽象为一个接口:可以是奔驰汽车,也可以是宝马汽车
8 public interface ICar {
9 //是汽车就应该能跑
10 public void run();
11 }
12 public class Benz implements ICar{
13 //汽车肯定会跑
14 public void run(){
15 System.out.println("奔驰汽车开始运行...");
16 }
17 }
18 public class BMW implements ICar{
19 //宝马车当然也可以开动了
20 public void run(){
21 System.out.println("宝马汽车开始运行...");
22 }
23 }
24 //高层模块
25 public class Client {
26 public static void main(String[] args) {
27 IDriver xiaoLi = new Driver();
28 ICar benz = new Benz();
29 //小李开奔驰车
30 xiaoLi.drive(benz);
31 }
32 }
33 ​

面向接口编程,司机依赖Icar接口,而不依赖实现类

5、接口隔离原则

1、客户端不应依赖它不需要的接口

2、类间的依赖关系应该建立在最小的接口上

  其实通俗来理解就是,不要在一个接口里面放很多的方法,这样会显得这个类很臃肿。接口应该尽量细化,一个接口对应一个功能模块,同时接口里面的方法应该尽可能的少,使接口更加灵活轻便。

或许有的人认为接口隔离原则和单一职责原则很像,但两个原则还是存在着明显的区别。单一职责原则是在业务逻辑上的划分,注重的是职责。接口隔离原则是基于接口设计考虑。

例如一个接口的职责包含10个方法,这10个方法都放在同一接口中,并且提供给多个模块调用,但不同模块需要依赖的方法是不一样的,这时模块为了实现自己的功能就不得不实现一些对其没有意义的方法,这样的设计是不符合接口隔离原则的。接口隔离原则要求"尽量使用多个专门的接口"专门提供给不同的模块。

6、合成复用原则

合成复用原则定义

合成复用原则(Composite Reuse Principle, CRP)又称为组合/聚合复用原则(Composition/ Aggregate Reuse Principle, CARP),其定义如下:

尽量使用对象组合,而不是继承来达到复用的目的。

包括组合关系和聚合关系)来使用一些已有的对象,使之成为新对象的一部分;新对象通过委派调用已有对象的方法达到复用其已有功能的目的。简言之:要尽量使用组合/聚合关系,少用继承。

在面向对象设计中,可以通过两种基本方法在不同的环境中复用已有的设计和实现,即通过组合/聚合关系或通过继承。

继承复用:实现简单,易于扩展。破坏系统的封装性,从基类继承而来的实现是静态的,不可能在运行时发生改变,没有足够的灵活性;只能在有限的环境中使用。(“白箱”复用 )

组合/聚合复用:耦合度相对较低,选择性地调用成员对象的操作;可以在运行时动态进行。(“黑箱”复用 )

7、迪米特法则

也叫最少知识原则。迪米特法则的定义是只与你的直接朋友交谈,不与"陌生人"说话。如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该应用。其目的是降低类之间的耦合度,提高模块的相对独立性。

  迪米特法则中的朋友是指:当前对象本身、当前对象的成员对象、当前对象所创建的对象、当前对象的方法参数等,这些对象存在关联、聚合或组合关系,可以直接访问这些对象的方法。

优点:

  1、降低类之间的耦合度,提高模块的相对独立性。

  2、由于亲和度降低,从而提高了类的可复用率和系统的扩展性。

缺点:

  过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低。所以,在釆用迪米特法则时需要反复权衡,确保高内聚和低耦合的同时,保证系统的结构清晰。

使用迪米特法则需要注意:

  1、在类的划分上,应该创建弱耦合的类。类与类之间的耦合越弱,就越有利于实现可复用的目标。

  2、在类的结构设计上,尽量降低类成员的访问权限。

  3、在类的设计上,优先考虑将一个类设置成不变类。

  4、在对其他类的引用上,将引用其他对象的次数降到最低。

  5、不暴露类的属性成员,而应该提供相应的访问器(set 和 get 方法)。

  6、谨慎使用序列化(Serializable)功能。

经典案例:

  明星与经纪人的关系实例。明星负责演出,经纪人负责处理日常事务,如与粉丝的见面会,与媒体公司的业务洽淡等。

第五周:面向对象部分内容总结(5)---java设计规则的更多相关文章

  1. 201671010140. 2016-2017-2 《Java程序设计》java学习第五周

    java学习第五周心得体会        本周,是Java学习第五周,随着时间推移,随着课本内容的推进,我们接触到的程序也开始变得越来越复杂,不再是二三章那些用来练手的小程序了,这一点,在我们的例题运 ...

  2. C语言程序设计I—第五周教学

    第五周教学总结(29/9-7/10) 本周为国庆节放假,周六周日提前补课,计算机专业已补,软件专业未补,由于国庆放假冲课不补,因此,软件专业在整体进度上落后计算机一次课,估计我要特别抽时间才能将进度拉 ...

  3. 第五周总结&第三次实验报告

    实验三 String类的应用 实验目的 掌握类String类的使用: 学会使用JDK帮助文档: 实验内容 1.已知字符串:"this is a test of java".按要求执 ...

  4. 对于“2017面向对象程序设计(Java)第五周工作总结”存在问题的反馈及本周教学计划

    一:问题反馈 “上周我们学习的新内容主要是第五章,并对第四章内容做了巩固.从学生上交的实验报告完成情况以及学习Java心得博客中的反馈可以看出,学生对构造器.重载.超类.多态.抽象类这几个概念理解的不 ...

  5. 201271050130-滕江南-《面向对象程序设计(java)》第十五周学习总结

    201271050130-滕江南-<面向对象程序设计(java)>第十五周学习总结 博文正文开头格式:(2分) 项目 内容 这个作业属于哪个课程 https://www.cnblogs.c ...

  6. 201871010111-刘佳华《面向对象程序设计(java)》第十五周学习总结

    201871010111-刘佳华<面向对象程序设计(java)>第十五周学习总结 实验十三  Swing图形界面组件(二) 实验时间 2019-12-6 第一部分:理论知识总结 5> ...

  7. 201871010123-吴丽丽《面向对象程序设计(Java)》第十五周学习总结

    201871010123-吴丽丽<面向对象程序设计(Java)>第十五周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...

  8. 201871010104-陈园园 《面向对象程序设计(java)》第十五周学习总结

    201871010104-陈园园 <面向对象程序设计(java)>第十五周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...

  9. 201871010105-曹玉中《面向对象程序设计(java)》第十五周学习总结

    201871010105-曹玉中<面向对象程序设计(java)>第十五周学习总结 项目 内容 这个作业属于哪个过程 https://www.cnblogs.com/nwnu-daizh/ ...

随机推荐

  1. File类与IO流

    一.File类与IO流 数组.集合等内容都是把数据放在内存里面,一旦关机或者断电,数据就会立刻从内存里面消失.而IO主要讲文件的传输(输入和输出),把内存里面的数据持久化到硬盘上,如.txt .avi ...

  2. 小程序开发-使用npm包

    微信小程序引用npm包 微信小程序官方支持使用npm包,地址为 https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html 实 ...

  3. 16_Python的包package

    1.包的概述 1.包是将模块一文件夹的组织形式进行分组管理的方法,一系列模块进行分类管理有利于防止命名冲突 2.包是一个包含多个模块的特色目录,目录下有一个特色的文件__init__.py 3.包的命 ...

  4. 从架构到部署,全面了解K3s

    Kubernetes无处不在--开发者的笔记本.树莓派.云.数据中心.混合云甚至多云上都有Kubernetes.它已然成为现代基础设施的基础,抽象了底层的计算.存储和网络服务.Kubernetes隐藏 ...

  5. java集合类源码学习一

    对于java的集合类,首先看张图 这张图大致描绘出了java集合类的总览,两个体系,一个Collection集合体系一个Map集合体系.在说集合类之前,先说说Iterable这个接口,这个接口在jdk ...

  6. Java 合并、拆分PPT幻灯片

    序 在日常使用PPT时,为了便于操作和管理文档,时常会遇到需要将PPT幻灯片进行合并或拆分的情况.本文将通过Java程序来演示如何进行上述操作. 示例要点: 1. 合并PPT幻灯片 1.1 将第一个P ...

  7. python2与python3同时安装

    安装步骤: 下载 1.第一步先下载python2和python3的安装包,下载地址:https://www.python.org/downloads/windows/ 下载之后,分别给python2和 ...

  8. 基于abp的小小设备控制系统设计

    客户有一堆小设备,需要通过小程序来控制它们,主要是设备门的开关.电源开关.状态查询.压力控制等.下面主要纪录下设计思路.源码地址:https://gitee.com/bxjg1987/abp 最初的设 ...

  9. C、算法、操作系统杂记《malloc 0大小是什么行为》

    linux手册上的说明 If size is 0, then malloc() returns either NULL, or a unique pointer value that can late ...

  10. openstack核心组件——keystone身份认证部署服务(5)

    node1主机执行 1.mysql -u root -p 2.create database keystone; 创建数据库 MariaDB [(none)]> show databases; ...