java求职学习day18

常用的设计原则和设计模式

1 常用的设计原则(记住)

1.1 软件开发的流程

需求分析文档、概要设计文档、详细设计文档、编码和测试、安装和调试、维护和升级

1.2 常用的设计原则

(1)开闭原则(Open Close Principle)
对扩展开放对修改关闭,为了使程序的扩展性好,易于维护和升级。
(2)里氏代换原则(Liskov Substitution Principle)
任何基类可以出现的地方,子类一定可以出现,多使用多态的方式。
(3)依赖倒转原则(Dependence Inversion Principle)
尽量多依赖于抽象类或接口而不是具体实现类,对子类具有强制性和规范性
(4)接口隔离原则(Interface Segregation Principle)
尽量多使用小接口而不是大接口,避免接口的污染,降低类之间耦合度。
(5)迪米特法则(最少知道原则)(Demeter Principle)
一个实体应当尽量少与其他实体之间发生相互作用,使系统功能模块相对独立。
高内聚,低耦合。
分析:
问题1:如何理解“高内聚,低耦合”?

我给大家举一个现实生活的例子吧,好吧,比如说我是java讲师。

意味着讲师应该具备的所有的技能,我是不是应该高度聚集于我一体?对吧,讲师要能讲课,讲师要能研发,讲师要能解决学员的问题,要能答疑。啊,讲师要能调试程序的bug。对吧,这些哎,该有的技能,我是不是要高度聚集于我一体,这就叫高内聚。

对吧哎,然后呢?低偶合什么意思?就是说我不该有的跟讲师无关的,那些工作内容我是不是应该减少关联啊?或者说关联的是不是越少越好?对吧,比如说跟什么呢?跟咱们啊行政的啊,老师之间的这个关联度是不是应该或者说他们的工作内容是不是这个关联度应该越少越好

(6)合成复用原则(Composite Reuse Principle)
尽量多使用合成/聚合的方式,而不是继承的方式。
分析:
问题2:如何理解合成复用原则?

所以大家以后呢,只要涉及当前类使用其他类就用合成复用原则。这个手法我们用的是非常多的。

2 常用的设计模式

2.1 基本概念

(1)设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
分析:
问题3:如何理解设计模式?
前人总结了很多的经验而把这些经验呢归纳起来,实际上就变成了设计模式。
(2)设计模式就是一种用于固定场合的固定套路。

2.2 基本分类

(1)创建型模式 - 单例设计模式、工厂方法模式、抽象工厂模式、...
(2)结构型模式 - 装饰器模式、代理模式、...
(3)行为型模式 - 模板设计模式、...

3 设计模式详解(重点)

3.1 单例设计模式

单例设计模式主要分为:饿汉式 和 懒汉式,懒汉式需要对多线程进行同步处理。
分析:

问题4:懒汉式线程如何同步实现?

那上面的问题应该如何解决呢?

那这个时候是不是就意味着我们需要对getInstance这个方法的?这种调用是不是要进行一个什么?线程同步的处理。也就是说我们在执行这段代码的时候,我们是不是应该是有且只能有一个线程进来执行,其他线程靠边。

这两种方式实际上是不是就是等价的一个效果。

问题5:懒汉式的线程同步为什么要优化以及如何优化?

但是这种写法啊,虽然能够实现线程同步的效果,但是还不够完美。哪块儿不太完美呢?是因为我们知道只有第一次调用get instance的方法的时候,我们是不是才需要把这段代码锁起来?对吧,而且的话实际上是new对象的这段代码是不是锁起来就够了,

往后我们第二次第三次甚至再往后再调get instance这个方法的时候还用得着再锁起来吗?不用,是不是直接把这个对象return出去就行?

对吧,那如果说每次调这个方法都是加锁,然后判断返回对象再解锁,然后再加锁,然后判断。然后返回对象再解锁,是不是就有点啰嗦了?是不是所以我们把这段代码还可以,怎么办?做一个简单的优化。

3.2 普通工厂模式

1 )基本概念
普通工厂方法模式就是建立一个工厂类,对实现了同一接口的不同实现类进行实例的创建。
分析:
问题6:如何理解工厂类?
那以前呢,都是让我们自己直接去new,现在我们自己都不用new了,把new对象的活儿。直接委派给一个工厂类了。明白这意思吧,也就是说通过工厂类来实现批量对象的生产。
2 )类图结构
分析:

那在这张图里面,其实大家可以看到这里面是不是有很多的方框啊?对不对?比如说这里面的方框都是什么意思?这里面的每一个方框实际上就是一个类或者接口的。明白这意思吧,哎,然后呢?

而且呢?在这个方框里面,其实大家会发现是不是有两条横线,两条横线,其实就是把这个方框的内容分成了几部分?三部分内容。上面的呢叫类名,然后中间的呢是这个类的成员变量,因为我们当前这个类的成员变量没有,所以这儿就空着没有写。明白这意思吧,然后下面是什么呢?下面是这个类的成员方法,然后方法名叫什么呢?叫produce这个方法呢?加号代表的是public修饰的。

然后呢?这个方法的返回值类型呢?是sender类型。然后这个方法的参数呢?是string类型的type。

清楚了吗?也就是说这个类图是不是够详细的了,因为它已经告诉你这个类叫什么,这个类里面有哪些成员变量都什么类型的,这个类中有哪些成员方法,方法的返回值类型参数?等等,是不都已经给我们标出来了。

上面的图转成代码:

接口:

接口实现类:

接口实现类:

工厂类(通过工厂类来实现批量对象的生产):

测试类:

问题7:普通工厂模式的意义是什么?

也就是说在以后的开发中,当我们需要涉及到大量对象的创建。而且的话呢,还想让它的维护性,扩展性更好一些,那我们是不是就可以写一个工厂类。
3 )主要缺点
在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,并且可能出现空指针异
常。

问题:8这个普通工厂方法模式里面呢?也有一个小小的问题,什么问题呢?

原来我是一个produce方法,然后根据参数传入的字符串来决定创建什么样的对象,并返回。

但是现在在这个工厂类中提供了两个工厂方法,一个是创建mail对象的。一个是用来创建sms对象的,不需要再传字符串了。避免了字符串的传入也就避免了空指针异常的发生。

那么在刚刚的这个案例代码中啊,我们说多个工厂方法模式比我们的普通工厂模式。比较有优势的一点在于什么地方?就是我们直接可以调用方法来创建具体的对象;不需要是不是再传字符串了,那不需要传字符串,是不是也就避免了空指针异常的发生。

3.3 多个工厂方法模式

1 )类图结构
2 )主要缺点
在多个工厂方法模式中,为了能够正确创建对象,先需要创建工厂类的对象才能调用工厂类中的生
产方法。

3.4 静态工厂方法模式

但是接下来我又有一个问题,请思考,请问上面这一行代码是干嘛的呀?

问题的具体体现:

是为了能够拿到这个类的引用点是不是去调用produce mail方法

那也就是说创建工厂类对象的价值仅仅是为了调用生产方法呗

所以说多个工厂方法模式还是不够优秀。也就是说多个工厂方法模式的话呢,实际上也有一个缺点,就是为了能够创建对象,我们得创建工厂类的对象,也就是说得创建sender factory这个类的对象之后。拿着这个类的引用,是不是才能调用produceMail?produceSms这样的方法,否则这俩方法是不是调用不了。

那现在我们就反推一下,我们能不能在调用这俩方法的时候,不需要创建这个类的对象。

可以,只需要给这两个方法变成什么来着,加上static关键字变成静态方法,隶属于类层级,是不是就可以直接用类名点调用。

所以我们又一次改进,提出了静态工厂方法模式

1 )类图结构
注:这里的SendFactory类和上面的不同之处是加了下划线(下划线就代表静态)
2 )实际意义
工厂方法模式适合:凡是出现了大量的产品需要创建且具有共同的接口时,可以通过工厂方法模式
进行创建。
3 )主要缺点
工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序生产新的产
品,就必须对工厂类的代码进行修改,这就违背了开闭原则。

因为我们现在的这个工厂类里面是不是只能创建MailSender对象和SmsSender对象。假设有一天客户提出新的需求,除了创建上面两个对象外,我还需要创建一个packet Sender类型对象。请问怎么做?

很简单呀,只需要在sender factory类里面增加一个叫producedPacket的方法不就可以了,这样做是可以的,但是这样做会违背我们讲过的开闭原则。还记得什么叫开闭原则吗?开闭原则的意思是对扩展开放,对修改关闭。也就是说,一旦我们一段代码写完之后,测试没问题,之后是不是尽量不要对这个原有的代码做任何的改变或者修改。那现在的话,我们如果增加方法,不就是对工厂类做修改了吗?

那有没有办法解决呀?可以我们又提出了另外一个模式,叫做抽象工厂模式

3.5 抽象工厂模式

1 )类图结构
所以一定要注意静态工厂模式和抽象工厂模式的最大的区别就是原来是一个工厂类,两个生产方法,现在变成了两个工厂类,各自有一个生产方法。
这样改进跟前面这种方式相比呢,有什么优势吗?
优势就在于如果有一天我们想要生产新的产品,比如说packetSender类,我们就可以在接口Provider中增加一个类。
那这样一来,原有的代码是不是一个字儿都不用变。也就意味着不用违背开闭原则了。
接口:
接口实现类1:
接口实现类2:
测试类:
那么介绍完抽象工厂模式之后啊,我们强调了它的一个理念就在于。如果我想要生产新的产品的时候,是不是它更有优势,而且不用违背开闭原则好,
那接下来我们就把这个代码写一写,比如说我现在想要增加一个PacketSender对象的发送,那问大家怎么办?
思路:

3.6 装饰器模式

1 )基本概念
装饰器模式就是给一个对象动态的增加一些新功能,要求装饰对象和被装饰对象实现同一个接口,
装饰对象持有被装饰对象的实例。
2 )类图结构
分析:大家会发现这儿有一个接口叫Sourceable的接口,里面是不是有一个叫method的抽象方法。 然后下面有俩实现类,一个是Source类,那这个source类啊,其实就是被装饰类,它实现Sourceable 接口。重写method方法明白了吧?后面呢,还有一个叫decorator,这么一个类,这个类呢,也是实现Sourceable 接口。然后那这个类是干嘛的呢?是装饰类,也就是这个类的价值是为了吧?对source被装饰类进行装饰的。明白了吧,然后它里面呢有一个成员变量是一个source able类型的source, 然后减号的意思是私有的成员变量嘛,然后因为实现了这个接口,当然也得重写method方法。能看明白这个类图的结构了吧。
通过运算结果我们知道:在保证原有功能不变的情况下,你看原有功能不变,我是不是又增加了一个新的功能,这就叫装饰模式。
以大家以后只要涉及到动态增加功能。我们就用装饰器模式。

3)实际意义

(3.1)可以实现一个类功能的扩展。
(3.2)可以动态的增加功能,而且还能动态撤销(继承不行)。
(3.3)缺点:产生过多相似的对象,不易排错。

3.7 代理模式

1 )基本概念
(1.1)代理模式就是找一个代理类替原对象进行一些操作。
(1.2)比如我们在租房子的时候找中介,再如我们打官司需要请律师,中介和律师在这里就是我们的代理。
2 )类图结构
也就是说这里面我可以直接new一个对象跟我们的装饰器模式做一个对比
装饰器模式是通过构造方法把这个原始对象是不是传过来?因为装饰嘛,我要在原有对象的基础上进行。但是代理模式实际上是不是就全权创建对象就可以了?还用再传过来吗?不用。我直接是不是自个new就完事了。
3 )实际意义
(3.1)如果在使用的时候需要对原有的方法进行改进,可以采用一个代理类调用原有方法,并且对产生的 结果进行控制,这种方式就是代理模式。
(3.2)使用代理模式,可以将功能划分的更加清晰,有助于后期维护。
4 )代理模式和装饰器模式的比较
4.1)装饰器模式通常的做法是将原始对象作为一个参数传给装饰者的构造器,而代理模式通常在一个代理类中创建一个被代理类的对象。
(4.2)装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。

3.8 模板方法模式

1 )基本概念
(1)模板方法模式主要指一个抽象类中封装了一个固定流程,流程中的具体步骤可以由不同子类进行不同的实现,通过抽象类让固定的流程产生不同的结果。
2 )类图结构
测试类:
3 )实际意义
将多个子类共有且逻辑基本相同的内容提取出来实现代码复用。
不同的子类实现不同的效果形成多态,有助于后期维护。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2025美赛美国大学生数学建模竞赛A题完整思路分析论文(43页)(含模型、可运行代码和运行结果)

2025美国大学生数学建模竞赛A题完整思路分析论文 目录 摘要 一、问题重述 二、 问题分析 三、模型假设 四、 模型建立与求解 4.1问题1 4.1.1问题1思路分析 4.1.2问题1模型建立 4.1.3问题1样例代码(仅供参考) 4.1.4问题1样例代码运行结果&…

UART ,IIC 和SPI三种总线协议

1.UART 1.1 简介 UART(Universal Asynchronous Receiver/Transmitter)即通用异步收发器。 常见的串行、异步通信总线,两条数据线Tx、Rx,实现全双工通信,常用于主机与外设的通信,点对点。 1.2 硬件连接 交叉…

IPhone14 Pro 设备详情

目录 产品宣传图内部图——后设备详细信息 产品宣传图 内部图——后 设备详细信息 信息收集于HubWeb.cn

海外问卷调查渠道查如何设置:最佳实践+示例

随着经济全球化和一体化进程的加速,企业间的竞争日益加剧,为了获得更大的市场份额,对企业和品牌而言,了解受众群体的的需求、偏好和痛点才是走向成功的关键。而海外问卷调查才是获得受众群体痛点的关键,制作海外问卷调…

如何跨互联网adb连接到远程手机-蓝牙电话集中维护

如何跨互联网adb连接到远程手机-蓝牙电话集中维护 --ADB连接专题 一、前言 随便找一个手机,安装一个App并简单设置一下,就可以跨互联网的ADB连接到这个手机,从而远程操控这个手机做各种操作。你敢相信吗?而这正是本篇想要描述的…

linux——进程树的概念和示例

一些程序进程运行后,会调用其他进程,这样就组成了一个进程树。 比如,在Windows XP的“运行”对话框中输入“cmd”启动命令行控制台,然后在命令行中输入“notepad”启动记事本,那么命令行控制台进程“cmd.exe”和记事本进程“note…

linux系统centos版本上安装mysql5.7

步骤 1: 安装 MySQL 5.7 添加 MySQL Yum Repository 首先,你需要添加 MySQL 的官方 Yum repository。打开终端并执行以下命令: sudo rpm -Uvh https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm 这条命令会为 CentOS 7 添加 MySQL…

Cross-Resolution知识蒸馏论文学习

TPAMI 2024:Pixel Distillation: Cost-Flexible Distillation Across Image Sizes and Heterogeneous Networks 教师模型使用高分辨率输入进行学习,学生模型使用低分辨率输入进行学习 学生蒸馏损失:Lpkd和Lisrd Lpkd:任务损失lo…

java爬虫工具Jsoup学习

目录 前言 一、基本使用 二、爬取豆瓣电影的案例 三、Jsoup能做什么? 四、Jsoup相关概念 五、Jsoup获取文档 六、定位选择元素 七、获取数据 八、具体案例 前言 JSoup是一个用于处理HTML的Java库,它提供了一个非常方便类似于使用DOM&#xff0…

29. 【.NET 8 实战--孢子记账--从单体到微服务】--项目发布

这是本专栏最后一篇文章了,在这片文章里我们不重点讲解如何配置服务器,重点讲如何发布服务,我们开始吧。 一、服务器配置 服务器配置包含:服务器的选择和项目运行环境的配置,下面我们分别来讲解一下。 在服务器选择上…

论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(五)

Understanding Diffusion Models: A Unified Perspective(五) 文章概括基于得分的生成模型(Score-based Generative Models) 文章概括 引用: article{luo2022understanding,title{Understanding diffusion models: A…

TOGAF之架构标准规范-信息系统架构 | 数据架构

TOGAF是工业级的企业架构标准规范,信息系统架构阶段是由数据架构阶段以及应用架构阶段构成,本文主要描述信息系统架构阶段中的数据架构阶段。 如上所示,信息系统架构(Information Systems Architectures)在TOGAF标准规…

自定义数据集 使用pytorch框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测

代码1实现逻辑回归并保存模型 import torch import numpy as np import torch.nn as nn from torch.utils.data import DataLoader, TensorDatasetdata [[-0.5, 7.7], [1.8, 98.5], [0.9, 57.8], [0.4, 39.2], [-1.4, -15.7], [-1.4, -37.3], [-1.8, -49.1], [1.5, 75.6],[0.…

基于回归分析法的光伏发电系统最大功率计算simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于回归分析法的光伏发电系统最大功率计算simulink建模与仿真。选择回归法进行最大功率点的追踪,使用光强和温度作为影响因素,电压作为输出进行建模。…

【数据结构】 并查集 + 路径压缩与按秩合并 python

目录 前言模板朴素实现路径压缩按秩合并按树高为秩按节点数为秩 总结 前言 并查集的基本实现通常使用森林来表示不同的集合,每个集合用一棵树表示,树的每个节点有一个指向其父节点的指针。 如果一个节点是它自己的父节点,那么它就是该集合的代…

Flutter android debug 编译报错问题。插件编译报错

下面相关内容 都以 Mac 电脑为例子。 一、问题 起因:(更新 Android studio 2024.2.2.13、 Flutter SDK 3.27.2) 最近 2025年 1 月 左右,我更新了 Android studio 和 Flutter SDK 再运行就会出现下面的问题。当然 下面的提示只是其…

CSAPP学习:前言

前言 本书简称CS:APP。 背景知识 一些基础的C语言知识 如何阅读 Do-做系统 在真正的系统上解决具体的问题,或是编写和运行程序。 章节 2025-1-27 个人认为如下章节将会对学习408中的操作系统与计算机组成原理提供帮助,于是先凭借记忆将其简单…

动态规划DP 数字三角型模型 方格取数(题目详解+C++代码实现)

方格取数 原题链接 AcWing 1027. 方格取数 题目描述 设有 NN 的方格图,我们在其中的某些方格中填入正整数,而其它的方格中则放入数字0。 如下图所示: 某人从图中的左上角 A 出发,可以向下行走,也可以向右行走&…

【Linux】20.基础IO(2)

文章目录 2. 理解文件系统2.1 inode2.2 如何理解目录2.3 硬链接2.4 软链接2.5 硬链接和软链接的区别 2. 理解文件系统 2.1 inode 我们使用ls -l的时候看到的除了看到文件名,还看到了文件元数据。 ydk_108iZuf68hz06p6s2809gl3i1Z:~/108/lesson20$ ll total 8 drw…

read+write实现:链表放到文件+文件数据放到链表 的功能

思路 一、 定义链表: 1 节点结构(数据int型) 2 链表操作(创建节点、插入节点、释放链表、打印链表)。 二、链表保存到文件 1打开文件 2遍历链表、写文件: 遍历链表,write()将节点数据写入文件。…