java求职学习day18

news2025/1/30 13:00:39

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

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 )实际意义
将多个子类共有且逻辑基本相同的内容提取出来实现代码复用。
不同的子类实现不同的效果形成多态,有助于后期维护。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

初阶2 类与对象

本章重点 上篇1.面向过程和面向对象初步认识2.类的引入---结构体3.类的定义3.1 语法3.2 组成3.3 定义类的两种方法: 4.类的访问限定符及封装4.1 访问限定符4.2封装---面向对象的三大特性之一 5.类的作用域6.类的实例化7.类对象模型7.1 如何计算类对象的大小 8.this指…

蓝桥杯模拟算法:多项式输出

P1067 [NOIP2009 普及组] 多项式输出 - 洛谷 | 计算机科学教育新生态 这道题是一道模拟题&#xff0c;我们需要分情况讨论&#xff0c;我们需要做一下分类讨论 #include <iostream> #include <cstdlib> using namespace std;int main() {int n;cin >> n;for…

深度剖析C++17中的std::optional:处理可能缺失值的利器

文章目录 一、基本概念与设计理念二、构建与初始化&#xff08;一&#xff09;默认构造&#xff08;二&#xff09;值初始化&#xff08;三&#xff09;使用std::make_optional&#xff08;四&#xff09;使用std::nullopt 三、访问值&#xff08;一&#xff09;value()&#x…

MySQL用户授权、收回权限与查看权限

【图书推荐】《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;》-CSDN博客 《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;&#xff08;数据库技术丛书&#xff09;》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…

【Maui】注销用户,采用“手势”点击label弹窗选择

文章目录 前言一、问题描述二、解决方案三、软件开发&#xff08;源码&#xff09;3.1 方法一&#xff1a;前端绑定3.2 方法二&#xff1a;后端绑定3.3 注销用户的方法 四、项目展示 前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架&#xff0c;用于使用 C# 和 XAML 创…

如何将xps文件转换为txt文件?xps转为pdf,pdf转为txt,提取pdf表格并转为txt

文章目录 xps转txt方法一方法二 pdf转txt整页转txt提取pdf表格&#xff0c;并转为txt 总结另外参考XPS文件转换为TXT文件XPS文件转换为PDF文件PDF文件转换为TXT文件提取PDF表格并转为TXT示例代码&#xff08;部分&#xff09; 本文测试代码已上传&#xff0c;路径如下&#xff…

Object类(2)

大家好&#xff0c;今天我们继续来看看Object类中一些成员方法&#xff0c;这些方法在实际中有很大的用处&#xff0c;话不多说&#xff0c;来看。 注&#xff1a;所有类都默认继承Object类的&#xff0c;所以可调用Object类中的方法&#xff0c;如equals&#xff0c;也可以发生…

BGP分解实验·11——路由聚合与条件性通告(3)

续接上&#xff08;2&#xff09;的实验。其拓扑如下&#xff1a; 路由聚合的负向也就是拆分&#xff0c;在有双出口的情况下&#xff0c;在多出口做流量分担是优选方法之一。 BGP可以根据指定来源而聚合路由&#xff0c;在产生该聚合路由的范围内的条目注入到本地BGP表后再向…

MOS的体二极管能通多大电流

第一个问题&#xff1a;MOS导通之后电流方向可以使任意的&#xff0c;既可以从D到S&#xff0c;也可以从S到D。 第二个问题&#xff1a;MOS里面的体二极管电流可以达到几百安培&#xff0c;这也就解释了MOS选型的时候很少考虑体二极管的最大电流&#xff0c;而是考虑DS之间电流…

C语言【基础篇】之流程控制——掌握三大结构的奥秘

流程控制 &#x1f680;前言&#x1f99c;顺序结构&#x1f4af; 定义&#x1f4af;执行规则 &#x1f31f;选择结构&#x1f4af;if语句&#x1f4af;switch语句&#x1f4af;case穿透规则 &#x1f914;循环结构&#x1f4af;for循环&#x1f4af;while循环&#x1f4af;do -…

Node.js下载安装及环境配置教程 (详细版)

Node.js&#xff1a;是一个基于 Chrome V8 引擎的 JavaScript 运行时&#xff0c;用于构建可扩展的网络应用程序。Node.js 使用事件驱动、非阻塞 I/O 模型&#xff0c;使其非常适合构建实时应用程序。 Node.js 提供了一种轻量、高效、可扩展的方式来构建网络应用程序&#xff0…

新型人工智能“黑帽”工具:GhostGPT带来的威胁与挑战

生成式人工智能的发展既带来了有益的生产力转型机会&#xff0c;也提供了被恶意利用的机会。 最近&#xff0c;Abnormal Security的研究人员发现了一个专门为网络犯罪创建的无审查AI聊天机器人——GhostGPT&#xff0c;是人工智能用于非法活动的新前沿&#xff0c;可以被用于网…

【文星索引】搜索引擎项目测试报告

目录 一、项目背景二、 项目功能2.1 数据收集与索引2.2 API搜索功能2.3 用户体验与界面设计2.4 性能优化与维护 三、测试报告3.1 功能测试3.2 界面测试3.3 性能测试3.4 兼容性测试3.5 自动化测试 四、测试总结4.1 功能测试方面4.2 性能测试方面4.3 用户界面测试方面 一、项目背…

【PostgreSQL内核学习 —— (WindowAgg(一))】

WindowAgg 窗口函数介绍WindowAgg理论层面源码层面WindowObjectData 结构体WindowStatePerFuncData 结构体WindowStatePerAggData 结构体eval_windowaggregates 函数update_frameheadpos 函数 声明&#xff1a;本文的部分内容参考了他人的文章。在编写过程中&#xff0c;我们尊…

【观察】甲骨文:以AI为中心,开启企业级平台架构“新革命”

知名科技杂志《连线》创始主编凯文凯利曾预测&#xff1a;“在未来的 100 年里&#xff0c;人工智能将超越任何一种人工力量&#xff0c;将人类引领到一个前所未有的时代。” 可以看到&#xff0c;随着近两年AIGC与大模型的快速爆发&#xff0c;AI在千万行业中的重要性愈发突出…

react native在windows环境搭建并使用脚手架新建工程

截止到2024-1-11&#xff0c;使用的主要软件的版本如下&#xff1a; 软件实体版本react-native0.77.0react18.3.1react-native-community/cli15.0.1Android Studio2022.3.1 Patch3Android SDKAndroid SDK Platform 34 35Android SDKAndroid SDK Tools 34 35Android SDKIntel x…

C语言从入门到进阶

视频&#xff1a;https://www.bilibili.com/video/BV1Vm4y1r7jY?spm_id_from333.788.player.switch&vd_sourcec988f28ad9af37435316731758625407&p23 //枚举常量 enum Sex{MALE,FEMALE,SECRET };printf("%d\n", MALE);//0 printf("%d\n", FEMALE…

Python案例--养兔子

兔子繁殖问题是一个经典的数学问题&#xff0c;最早由意大利数学家斐波那契在13世纪提出。这个问题不仅在数学领域具有重要意义&#xff0c;还广泛应用于计算机科学、生物学和经济学等领域。本文将通过一个具体的Python程序&#xff0c;深入探讨兔子繁殖问题的建模和实现&#…

若依基本使用及改造记录

若依框架想必大家都了解得不少&#xff0c;不可否认这是一款及其简便易用的框架。 在某种情况下&#xff08;比如私活&#xff09;使用起来可谓是快得一匹。 在这里小兵结合自身实际使用情况&#xff0c;记录一下我对若依框架的使用和改造情况。 一、源码下载 前往码云进行…

Java基础教程(007):方法的重载与方法的练习

文章目录 6.5 方法的重载6.6 方法练习数组遍历数组最大值 6.5 方法的重载 在 Java 中&#xff0c;方法的重载是指在同一个类中定义多个方法&#xff0c;这些方法具有相同的名称&#xff0c;但参数列表不同。方法的重载是一种实现多态的方式&#xff0c;允许一个方法名以不同的…