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

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

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

相关文章

c++ 定点 new

&#xff08;1&#xff09; 代码距离&#xff1a; #include <new> // 需要包含这个头文件 #include <iostream>int main() {char buffer[sizeof(int)]; // 分配一个足够大的字符数组作为内存池int* p new(&buffer) int(42); // 使用 placement new…

本地部署 DeepSeek-R1 大模型指南:基于 Ollama 的完整流程

Ollama是什么 Ollama 是一个开源的大语言模型本地化部署与管理工具&#xff0c;支持&#xff1a; 一键式模型下载与版本管理 本地化模型推理服务部署 REST API 接口提供 多平台客户端接入支持 整体步骤 安装 OllamaOllama服务配置部署模型客户端配置&#xff08;Page Ass…

Git Bash 配置 zsh

博客食用更佳 博客链接 安装 zsh 安装 Zsh 安装 Oh-my-zsh github仓库 sh -c "$(curl -fsSL https://install.ohmyz.sh/)"让 zsh 成为 git bash 默认终端 vi ~/.bashrc写入&#xff1a; if [ -t 1 ]; thenexec zsh fisource ~/.bashrc再重启即可。 更换主题 …

Controller 层优化四步曲

Controller 层优化四步曲 前言 在开发过程中&#xff0c;Controller 层作为系统与外界交互的桥梁&#xff0c;承担着接收请求、解析参数、调用业务逻辑、处理异常等职责。 然而&#xff0c;随着业务复杂度的增加&#xff0c;Controller 层的代码往往会变得臃肿且难以维护。 …

面试经典150题——图

文章目录 1、岛屿数量1.1 题目链接1.2 题目描述1.3 解题代码1.4 解题思路 2、被围绕的区域2.1 题目链接2.2 题目描述2.3 解题代码2.4 解题思路 3、克隆图3.1 题目链接3.2 题目描述3.3 解题代码3.4 解题思路 4、除法求值4.1 题目链接4.2 题目描述4.3 解题代码4.4 解题思路 5、课…

FLTK - FLTK1.4.1 - 搭建模板,将FLTK自带的实现搬过来做实验

文章目录 FLTK - FLTK1.4.1 - 搭建模板&#xff0c;将FLTK自带的实现搬过来做实验概述笔记my_fltk_test.cppfltk_test.hfltk_test.cxx用adjuster工程试了一下&#xff0c;好使。END FLTK - FLTK1.4.1 - 搭建模板&#xff0c;将FLTK自带的实现搬过来做实验 概述 用fluid搭建UI…

【外文原版书阅读】《机器学习前置知识》1.线性代数的重要性,初识向量以及向量加法

目录 ​编辑 ​编辑 1.Chapter 2 Why Linear Algebra? 2.Chapter 3 What Is a Vector? 个人主页&#xff1a;Icomi 大家好&#xff0c;我是Icomi&#xff0c;本专栏是我阅读外文原版书《Before Machine Learning》对于文章中我认为能够增进线性代数与机器学习之间的理解的…

Python设计模式 - 组合模式

定义 组合模式&#xff08;Composite Pattern&#xff09; 是一种结构型设计模式&#xff0c;主要意图是将对象组织成树形结构以表示"部分-整体"的层次结构。这种模式能够使客户端统一对待单个对象和组合对象&#xff0c;从而简化了客户端代码。 组合模式有透明组合…

Java 基于 SpringBoot 的校园外卖点餐平台微信小程序(附源码,部署,文档)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

当高兴、尊重和优雅三位一体是什么情况吗?

英语单词 disgrace 表示“失脸&#xff0c;耻辱&#xff0c;不光彩&#xff0c;名誉扫地”一类的含义&#xff0c;可做名词或动词使用&#xff0c;含义基本一致&#xff0c;只是词性不同。 disgrace n.丢脸&#xff1b;耻辱&#xff1b;不光彩&#xff1b;令人感到羞耻的人(或…

LeetCode热题100(八)—— 438.找到字符串中所有字母异位词

LeetCode热题100&#xff08;八&#xff09;—— 438.找到字符串中所有字母异位词 题目描述代码实现思路解析 你好&#xff0c;我是杨十一&#xff0c;一名热爱健身的程序员在Coding的征程中&#xff0c;不断探索与成长LeetCode热题100——刷题记录&#xff08;不定期更新&…

八股——Java基础(四)

目录 一、泛型 1. Java中的泛型是什么 ? 2. 使用泛型的好处是什么? 3. Java泛型的原理是什么 ? 什么是类型擦除 ? 4.什么是泛型中的限定通配符和非限定通配符 ? 5. List和List 之间有什么区别 ? 6. 可以把List传递给一个接受List参数的方法吗&#xff1f; 7. Arra…

naivecv的设计与实现(2): 读写gray和rgb图像

图像读写并不是图像处理的核心&#xff0c;仅仅作为调试工具&#xff0c; 是一种手段而非目的。 图像文件格式的选择 正因如此&#xff0c;对gray和rgb图像的读写&#xff0c;存在多种方法。 最常见的三种图像文件格式&#xff1a; bmppngjpg 实际上有更简单的方式&#xf…

设计壁纸时,色彩选择是至关重要的一步

在设计壁纸时&#xff0c;色彩选择是至关重要的一步&#xff0c;它直接影响到壁纸的整体视觉效果和情感传达。以下是一些色彩选择的技巧&#xff0c;帮助你在设计中更好地运用色彩&#xff1a; 一、了解色彩理论 色彩轮&#xff1a; 基本颜色&#xff1a;红、黄、蓝是三原色&am…

二次封装的方法

二次封装 我们开发中经常需要封装一些第三方组件&#xff0c;那么父组件应该怎么传值&#xff0c;怎么调用封装好的组件原有的属性、插槽、方法&#xff0c;一个个调用虽然可行&#xff0c;但十分麻烦&#xff0c;我们一起来看更简便的方法。 二次封装组件&#xff0c;属性怎…

c++多态

1.多态的概念 通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是去完成某个行为&#xff0c;当不同的对象去完成时会产生出不同 的状态。 2.多态的定义及实现 2.1多态的构成条件 多态是在不同继承关系的类对象&#xff0c;去调用同一函数&#xff0c;产生了不同的行为…

docker安装Redis:docker离线安装Redis、docker在线安装Redis、Redis镜像下载、Redis配置、Redis命令

一、镜像下载 1、在线下载 在一台能连外网的linux上执行docker镜像拉取命令 docker pull redis:7.4.0 2、离线包下载 两种方式&#xff1a; 方式一&#xff1a; -&#xff09;在一台能连外网的linux上安装docker执行第一步的命令下载镜像 -&#xff09;导出 # 导出镜像…

【unity游戏开发之InputSystem——07】InputSystem+UGUI配合使用(基于unity6开发介绍)

文章目录 一、InputSystem+UGUI配合使用1、官方文档参考2、切换到新的输入模块二、UGUI中的新输入系统输入模块参数相关1、Send Pointer Hover To Parent2、Move Repeat Delay3、Move Repeat Rate4、XR Tracking Origin5、Deselect On Background CLick6、Pointer Behavior7、S…

国内优秀的FPGA设计公司主要分布在哪些城市?

近年来&#xff0c;国内FPGA行业发展迅速&#xff0c;随着5G通信、人工智能、大数据等新兴技术的崛起&#xff0c;FPGA设计企业的需求也迎来了爆发式增长。很多技术人才在求职时都会考虑城市的行业分布和发展潜力。因此&#xff0c;国内优秀的FPGA设计公司主要分布在哪些城市&a…

汇编基础语法及其示例

1.汇编指令 1.1汇编指令的基本格式 <opcode>{<cond>}{s} <Rd> , <Rn> , <shifter_operand> <功能码>{<条件码>}{cpsr影响位} <目标寄存器> , <第一操作寄存器> , <第二操作数> 注&#xff1a;第一操作寄存器…