当前位置: 首页 > news >正文

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

相关文章:

java求职学习day18

常用的设计原则和设计模式 1 常用的设计原则(记住) 1.1 软件开发的流程 需求分析文档、概要设计文档、详细设计文档、编码和测试、安装和调试、维护和升级 1.2 常用的设计原则 (1)开闭原则(Open Close Principle…...

单链表专题(上)

链表的定义与创建 线性表: 1. 物理结构上不一定是线性的 2. 逻辑结构上一定是线性的 链表是一种物理存储结构上非连续,非顺序的存储结构 链表也是线性表的一种,但是在物理结构上不是连续的 链表是由一个一个的节点组成,需要数…...

【stm32学习】STM32F103相关特性

| 名称 | 缩写 | 频率 | 外部连接 | 功能 | 用途 | 特性 | |--------------------|------|----------------|---------------|------------|--------------|----------------| | 外部高速晶体振荡器 | HSE | 4~16MHz …...

PostGIS笔记:PostgreSQL中表、键和索引的基础操作

创建、查看与删除表 在数据库中创建一个表,使用如下代码: create table streets (id serial not null primary key, name varchar(50));这里的表名是streets,id是主键所以非空,采用serial数据类型,这个数据类型会自动…...

蓝桥杯python语言基础(3)——循环结构

一、for语句 理解range函数 range(start, stop, step) start: 序列开始的数字(默认为0)。stop: 序列结束的数字(不包含stop)。step: 步长(默认为1)。 练习 输出在 l 和 r 之间的所有偶数: pri…...

微服务网关鉴权之sa-token

目录 前言 项目描述 使用技术 项目结构 要点 实现 前期准备 依赖准备 统一依赖版本 模块依赖 配置文件准备 登录准备 网关配置token解析拦截器 网关集成sa-token 配置sa-token接口鉴权 配置satoken权限、角色获取 通用模块配置用户拦截器 api模块配置feign…...

23【进制的理解】

很多人可能听过计算机的最底层是2进制执行,但是原理并不知道,我们今天先不讨论那么复杂的问题,先讨论什么是进制 1910,10并不是1个字符,而是2个字符,也就是说在10进制里面没有“10”这个字符,1…...

jemalloc 5.3.0的tsd模块的源码分析

一、背景 在主流的内存库里,jemalloc作为android 5.0-android 10.0的默认分配器肯定占用了非常重要的一席之地。jemalloc的低版本和高版本之间的差异特别大,低版本的诸多网上整理的总结,无论是在概念上和还是在结构体命名上在新版本中很多都…...

【Convex Optimization Stanford】Lec3 Function

【Convex Optimization Stanford】Lec3 Function 前言凸函数的定义对凸函数在一条线上的限制增值扩充? 一阶条件二阶条件一些一阶/二阶条件的例子象集和sublevel set关于函数凸性的扩展(Jesen Inequality)保持函数凸性的操作非负加权和 & 仿射函数的…...

深入 Rollup:从入门到精通(三)Rollup CLI命令行实战

准备阶段:初始化项目 初始化项目,这里使用的是pnpm,也可以使用yarn或者npm # npm npm init -y # yarn yarn init -y # pnpm pnpm init安装rollup # npm npm install rollup -D # yarn yarn add rollup -D # pnpm pnpm install rollup -D在…...

wangEditor富文本编辑器,Laravel上传图片配置和使用

文章目录 前言步骤1. 构造好前端模版2. 搭建后端存储3. 调试 前言 由于最近写项目需要使用富文本编辑器,使用的是VUE3.0版本所以很多不兼容,实际测试以后推荐使用wangEditor 步骤 构造好前端模版搭建后端存储调试 1. 构造好前端模版 安装模版 模版安…...

chrome源码剖析—进程通信

Chrome 浏览器采用多进程架构(multi-process architecture),这种架构使得每个浏览器标签、扩展、插件、GPU 渲染等都在独立的进程中运行。为了确保不同进程之间的高效通信,Chrome 使用 进程间通信(IPC, Inter-Process …...

JJJ:linux时间子系统相关术语

文章目录 墙上时间内核管理的各种时间无时钟滴答模式(tickless mode 或 no-tick mode)简要介绍具体实现动态时钟滴答 Dynamic Ticks完全无时钟滴答(Full Tickless) nohz sleep单触发模式 oneshot mode 墙上时间 真实世界的真实时…...

0 基础学运维:解锁 K8s 云计算运维工程师成长密码

前言:作为一个过来人,我曾站在技术的门槛之外,连电脑运行内存和内存空间都傻傻分不清,完完全全的零基础。但如今,我已成长为一名资深的k8s云计算运维工程师。回顾这段历程,我深知踏上这条技术之路的艰辛与不…...

大一计算机的自学总结:位运算的应用及位图

前言 不仅异或运算有很多骚操作,位运算本身也有很多骚操作。(尤其后几个题,太逆天了) 一、2 的幂 class Solution { public:bool isPowerOfTwo(int n) {return n>0&&n(n&-n);} }; 根据二进制表示数的原理&#…...

计算机毕业设计Django+Tensorflow音乐推荐系统 机器学习 深度学习 音乐可视化 音乐爬虫 知识图谱 混合神经网络推荐算法 大数据毕设

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...

AI 图片涌入百度图库

在这个信息爆炸的时代,我们习惯了通过搜索引擎来获取各种想要的信息和图片。然而,现在打开搜索引擎看到的却是许多真假难辨的信息——AI图片,这部分数据正以惊人的速度涌入百度图库,让小编不禁想问:未来打开百度图库不…...

可爱狗狗的404动画页面HTML源码

源码介绍 可爱狗狗的404动画页面HTML源码,源码由HTMLCSSJS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果 效果预览 源码获取 可爱狗狗的404动画页面HTML源码...

【微服务与分布式实践】探索 Dubbo

核心组件 服务注册与发现原理 服务提供者启动时,会将其服务信息(如服务名、版本、所在节点的网络地址等)注册到注册中心。服务消费者则可以从注册中心发现可用的服务提供者列表,并与之通信。注册中心会存储服务的信息&#xff0c…...

OpenCSG月度更新2025.1

1月的OpenCSG取得了一些亮眼的成绩 在2025年1月,OpenCSG在产品和社区方面继续取得了显著进展。产品方面,推出了AutoHub浏览器自动化助手,帮助用户提升浏览体验;CSGHub企业版功能全面升级,现已开放试用申请&#xff0c…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋,无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话,配置.bahs_profile后也能解决上下翻页这些,但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...

微服务通信安全:深入解析mTLS的原理与实践

🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...

第八部分:阶段项目 6:构建 React 前端应用

现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...