设计模式面试题

概述

设计模式分类

  • 创建型模式
    用于描述“怎样创建对象”,主要特点是“将对象的创建与使用分离”。使用者不需要官族对象创建的细节。
  • 结构型模式
    用于描述如何将类或对象按照某种布局组成更大的结构。
  • 行为型模式
    用于描述类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,以及怎样分配职责。

类图

概述

  • 模型中的静态结构,描述了系统中类的集合,类的属性和类之间的关系;
  • 是系统分析和设计阶段的产物

表示

类的表示

包含类名、属性(field)和方法(method)且带有分割线的矩形表示
在这里插入图片描述
属性/方法名称前的 +- 等表示这个属性/方法的可见性

  • +: public
  • -: private
  • #: protected
    属性的完整表示方式为:** 可见性 名称 :类型 [ = 缺省值]**
    方法的完整表示方式为:** 可见性 名称(参数列表) [ : 返回类型]**

类和类之间关系的表示方式

关联关系

类和类之间最常用的关系,表示一类对象与另一类对象之间的联系。

  • 单向关联:用一个带箭头的实线表示。
    在这里插入图片描述- 双向关联:双方各自持有对方类型的成员变量,用无箭头实线表示。
    在这里插入图片描述- 自关联:用一个带有箭头并指向自身的线表示。
    在这里插入图片描述
聚合关系

强关联关系,表示整体和部分之间的关系。聚合关系也是通过成员对象实现,其中成员对象是整体对象中的一部分,但是成员对象可以单独存在。
使用带空心菱形的实线来表示,菱形指向整体。
在这里插入图片描述

组合关系

也是整体和部分的关系,其中整体对象可以控制部分对象的生命周期。一旦整体对象不存在,部分对象也无法独立存在。
用带实心菱形的实现表示,菱形指向整体。
在这里插入图片描述

依赖关系

一种使用关系,对象之间耦合度嘴弱的一种关联方式。在代码中,某一个类的方法通过局部变量、方法的参数或者对静态方法的调用来访问另一个类中的某些方法来完成一些职责。
用带箭头虚线表示,从使用类指向被依赖的类。
在这里插入图片描述

继承关系

对象之间耦合度最大的一种关系,用带空心三角箭头的实线来表示,箭头从子类指向父类。
在这里插入图片描述

实现关系

接口与实现类之间的关系,用带空心三角箭头的虚线表示,箭头从实现类指向接口。
在这里插入图片描述

设计原则

开闭原则

对扩展开放,对修改关闭。在程序需要进行扩展的时候,不能修改原有的代码,实现一个热插拔的效果。

里氏代换原则

任何基类可以出现的地方,子类一定可以出现。即子类可以扩展父类的功能,但是不能改变父类原有的功能。

依赖倒装原则

高层模块不应该依赖底层模块,两者都应当依赖抽象模块;抽象不应当依赖于细节,细节应当依赖于抽象。

接口隔离原则

客户端不应该被迫依赖于它不使用的方法;一个类对另一个类的依赖应该建立在最小的接口上。

迪米特法则

如果两个软件实体无需直接通信,那么就不应当发生直接的互相调用,可以通过第三方转发该调用。目的是降低类之间的耦合性,提高模块的相对独立性。

可以直接访问与当前对象存在关联、聚合或组合关系,可以直接访问这些对象的方法。

合成复用原则

尽量先使用组合或者聚合等关联关系方法来实现,其次才考虑继承关系来实现。

继承复用缺点

  • 破坏了类的封装性,会将父类的实现细节暴露给子类(白箱调用)
  • 子类和父类的耦合度高,父类的任何改变都会导致子类的实现发生变化
  • 限制了复用的灵活性,运行时不能发生变化

组合/聚合复用优点

  • 维持了类的封装性
  • 耦合度低,可以在类的成员位置声明抽象
  • 复用的灵活性高,可以在运行时动态引用与成分对象类型相同的对象。

创建者模式

单例设计模式(创建对象的最佳模式)

该种模式涉及一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。

  • 单例类:只能创建一个实例的类
  • 访问类:使用单例类

工厂方法模式

用于对象和对象之间解耦

简单工厂模式

包括如下角色:

  • 抽象产品:定义了产品的规范,描述产品的主要特性和功能
  • 具体产品:实现或者继承产品的子类
  • 具体工厂:提供创建产品的方法,调用者通过该方法来获取产品。

所有产品共有一个工厂,如果新增产品,则需要修改代码,也会违反开闭原则

工厂方法模式

给每个产品都提供了一个工厂,完全遵循开闭原则
主要角色:

  • 抽象工厂:提供创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品
  • 具体工厂:实现抽象工厂中的抽象方法,完成具体产品的创建
  • 抽象产品:定义了产品的规范,描述产品的主要特性和功能
  • 具体产品:实现了抽象产品角色所定义的接口,由具体工厂创建,同具体工厂之间一一对应。
    缺点:每新增一个产品都要增加新的产品类和工厂类,增加了代码复杂性

抽象工厂模式

工厂方法模式只考虑生产同等级产品,抽象工厂可以处理多等级产品的生产。使用一个超级工厂区创建其它工厂。

行为型模式

策略模式

  • 定义一系列算法,并将每个算法封装起来,使它们可以互相替换,且算法的变化不会影响使用算法的客户。
  • 通过对算法进行封装,将使用算法的责任与算法的实现分割开,并委派给不同的对象对这些算法进行管理。
    策略模式中主要角色如下:
  • 抽象策略类:一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有具体策略类所需的角色。
  • 具体策略类:实现了抽象策略类定义的接口,提供具体的算法实现或行为
  • 环境类:持有一个策略类的引用,最终给客户端调用


优点:

  • 策略类之间可以自由切换
  • 易于扩展
  • 避免使用多重条件选择语句
    缺点:
  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类
  • 策略模式将产生很多策略类

责任链设计模式

为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的应用而连城一条链;当有请求发生时,可以将请求沿着这条链传递,直到有对象处理它为止。
主要角色

  • 抽象处理者:定义一个处理请求的接口,包括抽象处理方法和一个后继连接
  • 具体处理者:实现抽象处理者的处理方法,判断能否处理本次请求。如果可以处理请求则处理,否则将该请求转给它的后继者。
  • 客户类角色:创建处理链,并向链头的具体处理者对象提交请求,不关心处理细节和请求传递过程。
    优点
  • 降低了对象之间的耦合度
  • 增强了系统的可扩展性
  • 增强了给对象指派职责的灵活性
  • 简化了对象之间的连接
  • 责任分担
    缺点
  • 针对较长的责任链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响
  • 责任链建立的合理性需要靠客户端来保证,增加了客户端的复杂性,可能会由于责任链的错误设置导致系统出错,甚至可能产生循环调用。

开闭原则 DEMO

抽象类

public abstract class AbstractSkin {
    public  abstract void display();
}

对抽象类的不同实现
DefaultSkin

public class DefaultSkin extends AbstractSkin{
    @Override
    public void display() {
        System.out.println("默认皮肤");
    }
}

NewSkin

public class NewSkin extends AbstractSkin{

    @Override
    public void display() {
        System.out.println("NEW SKIN");
    }
}

整合类

public class Test {
    public static void main(String[] args){
        SougouInput sougouInput = new SougouInput();
        //DefaultSkin skin = new DefaultSkin();
        NewSkin skin = new NewSkin();
        sougouInput.setSkin(skin);
        sougouInput.display();
    }
}

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

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

相关文章

面试经典150题——二叉树的最大深度

1. 题目描述 ​ 2. 题目分析与解析 这个题目有过一定基础的都应该知道,采用递归解决问题,因为要求一个二叉树的深度(也就是高度),其实上就是根节点的左子树和右子树中高度最高的那个。因此这个问题就可以拆解为&…

微服务之OpenFeign服务接口调用

一、概述 1.1简介 OpenFeign客户端是一个web声明式http远程调用工具,直接可以根据服务名称去注册中心拿到指定的服务IP集合,提供了接口和注解方式进行调用,内嵌集成了Ribbon本地负载均衡器。 Feign是一个声明性web服务客户端。它使编写web服…

BackTrader 中文文档(二十三)

原文:www.backtrader.com/ 基准测试 原文:www.backtrader.com/blog/posts/2016-07-22-benchmarking/benchmarking/ backtrader包括两种不同类型的对象,可以帮助跟踪: 观察者 分析器 问题 #89是关于添加针对资产的基准测试。这是…

[阅读笔记12][LLaVA-1.5]Improved Baselines with Visual Instruction Tuning

1.5版本是llava作者在23年10月提交的。 作者对原始的llava进行了四个很小的改进,之后就刷了11个数据集的sota。而且可以看到llava用于训练的数据量很小,与instructBLIP和通义千问比少多了。 然后这里就是llava1.5进行的四个小改进。 第一点是prompt明确短…

【Excel如何在表格中筛选重复的值之条件格式】

在使用excel进行统计时经常会遇到,数据统计出现重复的现象,为了确保数据的唯一性,可以用到条件格式筛选出重复值,以确保数据的正确性。 筛选重复值: 选中要筛选的范围,行或列或整个表选中【开始】-【条件…

vue快速入门(二十三)侦听器的简单写法与完整写法

注释很详细&#xff0c;直接上代码 上一篇 新增内容 侦听器简单写法侦听对象或属性侦听器完整写法侦听对象&#xff08;可选深度侦听&#xff09; 源码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name…

Zookeeper(从入门到掌握)看完这一篇就够了

文章目录 一、初识 Zookeeper1.Zookeeper 概念2.Zookeeper 数据模型3.Zookeeper 服务端常用命令4.Zookeeper 客户端常用命令 二、ZooKeeper JavaAPI 操作1.Curator 介绍1.Curator API 常用操作&#xff08;1&#xff09;建立连接&#xff08;2&#xff09;添加节点&#xff08;…

C#版Facefusion ,换脸器和增强器

C#版Facefusion &#xff0c;换脸器和增强器 目录 说明 效果 项目 调用代码 说明 Facefusion是一款最新的开源AI视频/图片换脸项目。是原来ROOP的项目的延续。项目官方介绍只有一句话&#xff0c;下一代换脸器和增强器。 代码实现参考 https://github.com/facefusion/f…

AI天使汇联合150家顶级基金、战投,征集优秀AI创业项目

鉴于AI天使汇主办的2024年3月期优秀项目征集活动效果超出预期&#xff0c;3月活动最后TOP20路演者中已有多家快速拿到了TS。 路演活动质量受到了AI创业公司和基金/战投伙伴的高度评价&#xff0c;现在开始四月期活动报名! 本期征集活动联合的顶级基金和战投数量增加到了150家…

Shell脚本学习(一):Shell内置命令与Shell运算符

Shell内置命令 理解内置命令的含义。 内置命令介绍 Shell内置命令&#xff0c;就是由Bash Shell自身提供的命令&#xff0c;而不是文件系统中的可执行文件。 使用type 可以用来确定一个命令是否是内置命令&#xff1a; type 命令演示&#xff1a; 对于上述演示的两个命令来…

【我的代码生成器】生成React页面类

有了数据表的结构信息&#xff0c;就能生成React 的页面类&#xff0c;快捷方便。 生成界面如下&#xff1a; 生成的React FrmUser.js页面如下&#xff1a; 只需再写里面的操作逻辑代码。

链表创建的陷阱与细节

链表是线性表的一种&#xff0c;它在逻辑结构上是连续的&#xff0c;在物理结构上是非连续的。 也就是说链表在物理空间上是独立的&#xff0c;可能是东一块西一块的。如下顺序表和链表在内存空间上的对比&#xff1a; 而链表的每一块空间是如何产生联系实现在逻辑结构上是连续…

关于java中的线程池用法

目录 线程池的参数介绍 线程池的工作流程 使用Executors创建常见的线程池 池的思想&#xff0c;在计算机中是非常普遍的概念。顾名思义&#xff0c;池是将一个或多个任务提前创建好&#xff0c;放入容器中&#xff0c;当程序运行的时候直接取出使用&#xff0c;这个容器就叫…

Imagination APXM-6200 CPU:性能卓越,安全可信

随着消费类和工业应用行业的不断发展&#xff0c;对创新性能和效率的需求永不停歇&#xff0c;我们自豪地推出旗下 Catapult CPU 系列的第二款产品&#xff1a;Imagination APXM-6200 CPU 。这款 64 位的高效 RISC-V 应用处理器具有强大的 AI 功能及性能密度&#xff0c;能够为…

基于Java+SpringBoot3+vue3健身房管理系统设计与实现

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

使用openLayers报错Module parse failed: Unexpected token

引入OpenLayers时报错 JavaScript模块解析失败 在构建工具中配置 transpileDependencies 参数&#xff0c;因为 ol 依赖库基于一个目标环境不支持的 ES 版本撰写&#xff0c;将该依赖添加进 vue.config.js 中的 transpileDependencies 选项中 // including the package "…

ruoyi单体+react+antdesign

基于ruoyi vue和Ruoyi-React实现的快速开发工具。 源码地址&#xff1a;GitHub - hebian1994/ruoyi-react-single: use ruoyi to generage java backend code and reacr front end code 前端&#xff1a;基于ant-design-pro 后端&#xff1a;单体springboot项目(非cloud)mysq…

亚马逊云科技数据工程师考试官方免费课程上线啦

自从上次小李哥分享了AWS Data Engineer Associate证书首通经验后&#xff0c;有非常多的小伙伴们问我&#xff0c;应该怎么复习这门考试呢&#xff1f; 这门考试是AWS针对最近大热&#x1f525;的AI、数据分析、数据科学等行业&#xff0c;推出的全新考试。因为刚刚推出&#…

神经网络背后的数学原理

原文地址&#xff1a;The Math Behind Neural Networks 2024 年 3 月 29 日 深入研究现代人工智能的支柱——神经网络&#xff0c;了解其数学原理&#xff0c;从头开始实现它&#xff0c;并探索其应用。 神经网络是人工智能 &#xff08;AI&#xff09; 的核心&#xff0c;为…

uni-start初始化后的微信登录问题

1.使用微信登录 一直提示“获取第三方账号失败”&#xff0c; 原来是在unicloud-->cloudfunctions-->common-->uni-config-center-->uni-id-->config.json文件中配置的微信的appid和appsecret有错误,配置好后就可以获取信息了。 2. 获取信息之后用真机调试报错…