如何理解面向对象的OO设计原则和设计模式?

一、如何理解面向对象的编程原则?

在这里插入图片描述

单一职责原则(Single Responsibility Principle)

  • 一个类,应该由一组相关性很高的数据和方法组成。
  • 一个类应该仅有一个引起它变化的原因。

单一职责最难界定的就是关于“职责”的定义,往往需要丰富的经验和对业务的认知程度,这也更加容易引起撕逼大战,似乎任何时候都可以拿它来辩论。如设计 ImageLoader 时,图片缓存功能和图片加载逻辑应该分开写在不同的类中。再比如在 Android 开发的早期 MVC 盛行,什么都往 Activity 里面加(网络请求、Adapter、Bean)导致 Activity 臃肿,这是典型的没有遵守单一职责造成的。

下面是违反单一职责原则的反例:

在这里插入图片描述
在这里插入图片描述

如果这样设计,随着需要实现的不同功能的类越来越多,这样的实现方式就会变成一种继承灾难。
在这里插入图片描述

  • 出现棱形继承,是抽象程度不够的表现。

单一职责原则的关键词:

  • 封装性
  • 职责划分
  • 细化抽象粒度

开闭原则(Open Closed Principle)

  • 对扩展开放,对修改关闭。

当软件需要变化时,尽量通过扩展的方式来实现变化,而不是通过修改已有代码。通常情况下继承是最简单的方式,因为这种方式能保证已经正常 work 的代码不动,但扩展的方式不仅仅是通过继承,更多的是通过持有抽象来拥抱不同的变化。例如 ImageLoader 可以通过持有一个 ImageCache 的接口类型变量,在使用时需要提供不同缓存策略时,set 方法注入 ImageCache 接口的不同实现,达到不修改已有类的目的。

下面是违反开闭原则的例子:

在这里插入图片描述

正确的做法:

在这里插入图片描述

  • 在面向对象语言里,提高代码可维护性的过程,大多数时候都是在消除条件分支语句(if & else )。

开闭原则的关键词:

  • 可扩展性
  • 抽象变化
  • 可维护性
  • 灵活性
  • 稳定性

里氏代换原则(Liskov Substitution Principle )

  • 任何基类出现的地方,子类也同样适用,是多态的体现。
  • 里氏代换,是开闭原则的一种实现方案,也是大部分设计模式的基础。
  • 只有满足里氏代换,子类能替换基类,才能够说明基类是真正能够被复用的。

比如 show(View) 方法传入不同的子类实现 TextView、 ImageView 等,就是使用 View 的不同子类来替换基类 View。再比如 Solider 类持有一把抽象的枪 Gun,使用时再传入具体的实现。因此一般持有抽象的类成员、方法参数都可以认为是里氏替换的例子。里氏替换的核心原理是抽象,且子类必须完全实现父类的方法,否则,应该用组合代替继承。

里氏替换的例子:
在这里插入图片描述
代理模式:
在这里插入图片描述

  • 这里代理者和被代理者都实现了同样的接口,定义代理者时使用基类来引用。只有这样基类才是可复用的。

里氏代换原则的关键词:

  • 可扩展性
  • 抽象
  • 可维护性
  • 复用基类
  • 开闭原则

依赖倒置原则(Dependence Inversion Principle)

  • 依赖抽象接口,而非具体实现。

依赖倒置原则一句话就是:面向接口编程,或面向抽象编程。因为类与类之间一旦依赖于细节,就会产生耦合,例如 ImageLoader 中的缓存策略依赖于某一种具体的实现 MemoryCache 而不是 ImageCache 接口,这样需要更换缓存策略时就会不停的修改 ImageLoader 类。

在这里插入图片描述
在这里插入图片描述

  • 比如,业务类中写了 18 层的继承关系,每一层都是实现类,还依赖了其他实现类,让人理不清关系。

依赖倒置原则的最大好处:降低耦合、隔绝变化

  • 不同业务之间,不被彼此的变化影响;
  • 明确开发、测试人员职责,提高协作效率;
  • 故障隔离,单独业务的故障问题,不应该影响全局。

依赖倒置原则的关键词:

  • 低耦合
  • 隔绝变化
  • 扩展性
  • 灵活性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/310489.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023年终总结:耕辍断续应犹在,碌而不暇仍少年

Author:AXYZdong 硕士在读 工科男 有一点思考,有一点想法,有一点理性! 定个小小目标,努力成为习惯!在最美的年华遇见更好的自己! CSDNAXYZdong,CSDN首发,AXYZdong原创 唯…

最优轨迹生成(一)—— 微分平坦

本系列文章是学习深蓝学院-移动机器人运动规划课程第五章最优轨迹生成 过程中所记录的笔记,本系列文章共包含四篇文章,依次介绍了微分平坦特性、无约束BVP轨迹优化、无约束BIVP轨迹优、 带约束轨迹优化等内容 本系列文章链接如下: 最优轨迹生…

欢迎来到Web3.0的世界:Solidity智能合约安全漏洞分析

智能合约概述 智能合约是运行在区块链网络中的一段程序,经由多方机构自动执行预先设定的逻辑,程序执行后,网络上的最终状态将不可改变。智能合约本质上是传统合约的数字版本,由去中心化的计算机网络执行,而不是由政府…

啊哈c语言——4.6循环嵌套来了(练习)

1.请尝试用while循环打印下面的图形。 还未解出:有会的大神可以提点一下 !!!!!!!!!!!!!&#xff0…

【Linux】chage命令使用

chage命令 chage用来更改linux用户密码到期信息,包括密码修改间隔最短、最长日期、密码失效时间等。 语法 chage [参数] 用户名 chage命令 -Linux手册页 选项及作用 执行令 : chage --help 执行命令结果 参数 -d, --lastday 最近日期 …

go的json数据类型处理

json对象转slice package mainimport ("encoding/json""fmt""github.com/gogf/gf/container/garray" )func main() {// JSON 字符串jsonStr : ["apple", "banana", "orange"]//方法一:// 解析 JSON 字…

操作系统:linux(在虚拟机上详细步骤安装)Centos

文章目录 前言:一、如何在自己的电脑上安装centos?二、在虚拟机上安装centos2.1安装步骤: 前言: 操作系统有:windows server 不开源的收费的、linux 开源的免费的,精简安装(没有UI)。国产的操作系统有&am…

#前后端分离# 头条发布系统

头条业务简介 用户功能 注册功能登录功能jwt实现 新闻 新闻的分页浏览通过标题关键字搜索新闻查看新闻详情新闻的修改和删除 预览界面 开源上线 https://gitcode.net/NVG_Haru/NodeJS_5161447 数据库设计 数据库脚本 CREATE DATABASE sm_db;USE sm_db;SET NAMES utf8mb4…

Spark的错误处理与调试技巧

Apache Spark是一个强大的分布式计算框架,用于处理大规模数据。在开发和运行Spark应用程序时,经常会遇到各种错误和问题。了解Spark的错误处理与调试技巧是解决这些问题的关键。本文将深入探讨Spark中常见的错误类型、调试工具和技巧,并提供丰…

软件测试/测试开发丨Python 内置库 正则表达式re

什么是正则表达式 正则表达式就是记录文本规则的代码可以查找操作符合某些复杂规则的字符串 使用场景 处理字符串处理日志 在 python 中使用正则表达式 把正则表达式作为模式字符串正则表达式可以使用原生字符串来表示原生字符串需要在字符串前方加上 rstring # 匹配字符…

[C#]C# winform实现imagecaption图像生成描述图文描述生成

介绍: 地址:C#https://github.com/ruotianluo/ImageCaptioning.pytorch 效果: 测试环境: vs2019 onnxruntime1.16.3 opencvsharp4.8 代码: using System; using System.Collections.Generic; using System.Comp…

网络故障排查和流量分析利器-Tcpdump命令

Tcpdump是一个在Unix/Linux系统上广泛使用的命令行网络抓包工具。它能够捕获经过网络接口的数据包,并将其以可读的格式输出到终端或文件中。Tcpdump是一个强大的命令行工具,能够捕获和分析网络数据包,为网络管理员和安全专业人员提供了深入了…