整理好了!2024年最常见 20 道设计模式面试题(七)

上一篇地址:整理好了!2024年最常见 20 道设计模式面试题(六)-CSDN博客

十三、请解释桥接模式,并给出一个使用场景。

桥接模式(Bridge Pattern)是一种结构型设计模式,它将抽象部分与其实现部分分离,使它们可以独立地变化。这种模式主要用于解决当一个类存在多个维度的变化时,如何避免使用多重继承带来的复杂性问题。

桥接模式的组成部分:

  1. 抽象(Abstraction):定义了客户端使用的接口,它维持了一个指向实现化角色的引用。
  2. 扩展抽象(Refined Abstraction):扩展了抽象类,添加了更多的业务方法。
  3. 实现化角色(Implementor):定义了实现化对象的接口,不依赖于抽象角色。
  4. 具体实现化(Concrete Implementor):实现了实现化角色定义的接口,具体实现了某种业务。

桥接模式的工作原理:

  • 抽象类定义了业务接口,并且包含一个实现化角色的引用。
  • 扩展抽象类继承自抽象类,增加了一些业务方法,这些方法可能会调用实现化角色的方法。
  • 实现化角色定义了一组接口,这些接口可以被不同的具体实现化类实现。
  • 具体实现化类实现了实现化角色定义的接口,提供了具体的实现。

使用场景:

假设我们正在开发一个图形绘制程序,该程序可以绘制多种形状,并且可以以不同的颜色绘制。这里的形状和颜色是两个变化的维度,使用桥接模式可以很好地解决这个问题。

  • 抽象(Shape):定义了绘制形状的接口。
  • 扩展抽象(ColoredShape):扩展了形状,增加了颜色属性和绘制带颜色的形状的方法。
  • 实现化角色(DrawAPI):定义了绘制接口,不依赖于形状。
  • 具体实现化(RedPen, BluePen):实现了DrawAPI接口,分别提供了红色和蓝色的绘制实现。

代码示例(伪代码):

// 抽象形状类
class Shape {protected DrawAPI drawAPI;public Shape(DrawAPI drawAPI) {this.drawAPI = drawAPI;}public abstract void draw();
}// 扩展抽象类,带颜色的形状
class ColoredShape extends Shape {private String color;public ColoredShape(DrawAPI drawAPI, String color) {super(drawAPI);this.color = color;}public void draw() {drawAPI.draw(color);}
}// 绘制接口
interface DrawAPI {void draw(String color);
}// 具体实现化类:红色笔
class RedPen implements DrawAPI {public void draw(String color) {System.out.println("Drawing with " + color + " pen.");}
}// 具体实现化类:蓝色笔
class BluePen implements DrawAPI {public void draw(String color) {System.out.println("Drawing with " + color + " pen.");}
}// 客户端代码
Shape shape = new ColoredShape(new RedPen(), "Red");
shape.draw(); // 输出: Drawing with Red pen.shape = new ColoredShape(new BluePen(), "Blue");
shape.draw(); // 输出: Drawing with Blue pen.

通过桥接模式,我们可以轻松地添加新的形状或颜色,而不需要修改现有的类结构。这提高了系统的可扩展性和可维护性。

十四、责任链模式是如何工作的?它在哪些情况下特别有用?

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许将请求沿着处理者对象的链进行传递,直到有一个处理者对象能够处理这个请求为止。这种模式可以避免请求的发送者和接收者之间的耦合关系,让多个对象都有可能接收请求,从而避免它们之间的耦合。

责任链模式的组成部分:

  1. 处理者(Handler):定义了一个处理请求的接口,所有具体处理者都实现这个接口。
  2. 具体处理者(Concrete Handler):实现处理者接口,并对请求进行处理。如果能够处理请求,则处理之;否则,将请求传递给链中的下一个处理者。
  3. 请求(Request):需要被处理者处理的请求。

责任链模式的工作原理:

  1. 每个具体处理者对象都有权决定是否处理这个请求。
  2. 一个具体处理者对象接收到请求后,如果能够处理这个请求,则处理它;否则,将请求传递给链中的下一个处理者对象。
  3. 请求沿着责任链一直传递,直到有一个处理者对象能够处理这个请求为止,或者直到链的末端都没有处理者处理这个请求。

使用场景:

责任链模式特别适用于以下情况:

  • 当多个对象可以处理同一个请求,但具体由哪个对象处理应由程序运行时刻自动确定。
  • 当你想将请求的处理者对象集合起来,让它们有序地、链式地处理请求,而不需要显式地指定哪个处理者对象处理它。
  • 当需要动态地增加或删除责任链中的处理者时。

代码示例(伪代码):

// 处理者接口
interface Handler {void setNext(Handler handler);void handleRequest(Request request);
}// 具体处理者A
class ConcreteHandlerA implements Handler {private Handler next;public void setNext(Handler handler) {this.next = handler;}public void handleRequest(Request request) {if (request.getType() == "A") {System.out.println("Handled by A");} else if (next != null) {next.handleRequest(request);}}
}// 具体处理者B
class ConcreteHandlerB implements Handler {private Handler next;public void setNext(Handler handler) {this.next = handler;}public void handleRequest(Request request) {if (request.getType() == "B") {System.out.println("Handled by B");} else if (next != null) {next.handleRequest(request);}}
}// 请求对象
class Request {private String type;public String getType() {return type;}
}// 客户端代码
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
handlerA.setNext(handlerB); // 构建责任链Request request1 = new Request();
request1.setType("A");
handlerA.handleRequest(request1); // 输出: Handled by ARequest request2 = new Request();
request2.setType("B");
handlerA.handleRequest(request2); // 输出: Handled by B

在这个示例中,我们创建了两个具体处理者ConcreteHandlerAConcreteHandlerB,它们分别处理类型为"A"和"B"的请求。通过设置setNext方法,我们构建了一个责任链。当请求被发送到handlerA时,它首先检查自己是否可以处理,如果可以,则处理之;否则,将请求传递给handlerB

责任链模式可以有效地将请求的处理逻辑从请求的发送者中解耦出来,使得系统更加灵活和易于扩展。

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

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

相关文章

fastadmin完全自定义页面内容

fastadmin的后台管理页面全自动生成非常方便,但是有些复杂查询确不太好弄,需要完全自定义,但是遵从以下几个步骤即可轻松定制了 1.随便使用某个数据表生成页面所需内容 通过命令工具即可完成 2.自定义返回内容 在controller的index方法里面,删除掉原来返回的内容(主要是aja…

通过数字证书获取CRL吊销列表

在一些对安全性要求比较严格的企业,需要在每次使用证书时,要求对证书的有效性进行验证,如何验证可查看我的其他博客。其中验证的吊销列表(CRL)是可以从数字证书中获取吊销列表文件的发布地址的。 一、一般CRL的使用场景设计 证书颁发机构对CRL的发布也不是实时的,在证书…

计算机网络 —— 应用层(DHCP)

计算机网络 —— 应用层(DHCP) 什么是DHCPDHCP工作过程DHCP DISCOVERDHCP OFFERDHCP RQUESTDHCP ACK DHCP租约机制中继代理工作原理功能与优势 我们今天来计网的DHCP: 什么是DHCP DHCP(Dynamic Host Configuration Protocol&…

2024年,收付通申请开通流程

大家好,今天咱们来聊聊关于APP场景中开通微信收付通的一些实用小窍门。在如今的移动互联网时代,很多商家都选择通过APP来提供服务和产品,因此如何在APP中顺利集成微信收付通功能,让用户能够轻松完成支付,就显得尤为重要…

分支结构相关

1.if 语句 结构: if 条件语句: 代码块 小练习: 使用random.randint()函数随机生成一个1~100之间的整数,判断是否是偶数 import random n random.randint(1,100) print(n) if n % 2 0:print(str(n) "是偶数") 2.else语…

Vue中使用ElementUI组件Form组件的校验validate

先准备一些el-form元素 这里面el-form中:model(v-bind:model)是单项绑定的,如果你写成了v-model""可能会出现校验没有效果的情况。 这是校验过后的结果了 现在开始使用下吧! 1.在el-form中绑定一个ref,名字自拟,后续触发检验结果…

代码随想录算法训练营第四十四天|LeetCode198 打家劫舍、LeetCode213 打家劫舍Ⅱ

题1: 指路:198. 打家劫舍 - 力扣(LeetCode) 思路与代码: 对于这个题,拿房屋i举例,我们需要考虑的是否确定偷取这个房屋,如果确定偷取这个房屋,那么我们将得到房屋i的金…

QT-QPainter实现一个动态充电的电池

1、效果 2、核心代码 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimer>

php反序列化的一些知识

问题 <?php $raw O:1:"A":1:{s:1:"a";s:1:"b";}; echo serialize(unserialize($raw)); //O:1:"A":1:{s:1:"a";s:1:"b";}?> php反序列化的时按理说找不到A这个类&#xff0c;但是他没有报错&#xff0c;…

SpringBoot复习

第一章 SpringBoot开发入门 1.Springboot的优点。 ① 可快速构建独立的Spring应用。 ② 直接嵌入Tomcat、Jetty和Undertow服务器&#xff08;无须部署WAR文件&#xff09; ③ 通过依赖启动器简化构建配置 ④ 自动化配置Spring和第三方库 ⑤ 提供生产就绪功能 ⑥ 极少的代码生成…

使用Docker Compose运行Elasticsearch

使用Docker Compose运行Elasticsearch可以帮助你快速搭建和管理Elasticsearch服务。以下是具体步骤&#xff1a; 1. 安装Docker和Docker Compose 确保你已经安装了Docker和Docker Compose。如果没有安装&#xff0c;可以参考官方文档进行安装&#xff1a; Docker安装指南Doc…

永久更改R包的安装目录

要永久更改 R 包的安装目录&#xff0c;可以通过设置 R 配置文件来实现。以下是步骤说明&#xff1a; 1. 查找和修改 R 配置文件 R 有几个配置文件用于保存用户和系统的设置&#xff1a; 用户级配置文件&#xff1a;通常位于 ~/.Rprofile系统级配置文件&#xff1a;通常位于…

HJY-91A/8J电压继电器10-242VAC 辅助电源220VDC 约瑟JOSEF

系列型号 HJY-E1A/4D数字式交流电压继电器&#xff1b;HJY-E1A/4J数字式交流电压继电器&#xff1b; HJY-E1B/4D数字式交流电压继电器&#xff1b;HJY-E1B/4J数字式交流电压继电器&#xff1b; HJY-E2A/4D数字式交流电压继电器&#xff1b;HJY-E2A/4J数字式交流电压继电器&…

【Android面试八股文】你刚刚提到了V2签名使用美团的Walle实现多渠道打包,那么你能讲一讲Android 签名的 v1、v2、v3、v4版本的区别吗?

文章目录 前言一、简介二、APK 签名方案 v1 (JAR签名)2.1. 签名过程2.2 验证过程2.3 详细例子2.4 优缺点2.5 美团基于V1版本的多渠道打包方案三、APK 签名方案 v23.1 为什么要设计APK 签名方案 v2 ?3.2 APK 签名方案 v2 : 签名前和签名后的 APK3.2.1 签名前和签名后的 APK3.2…

[17] 使用Opencv_CUDA 进行滤波操作

使用Opencv_CUDA 进行滤波操作 邻域处理操作 > 滤波操作&#xff0c;拒绝或者允许某特定频段通过如果图像某处的灰度级变化缓慢&#xff0c;那么就是低频区域&#xff0c;如果灰度级变化剧烈&#xff0c;就是高频区域邻域滤波即卷积操作形态学处理&#xff1a;膨胀&#xf…

Harmony学习(一)

1.arkts基础 //变量的存储和修改&#xff08;string number boolea&#xff09; let title:string 字符串类型 let num:number 21.4 let isLogin:boolean false title 字符串hhhhh console.log(title,isLogin,num) //常量 const PI: number 3.1435 console.log(pi,PI)…

全网最全postman接口测试教程和项目实战~从入门到精通

Postman实现接口测试内容大纲一览&#xff1a; 一、什么是接口&#xff1f;为什么需要接口&#xff1f; 接口指的是实体或者软件提供给外界的一种服务。 因为接口能使我们的实体或者软件的内部数据能够被外部进行修改。从而使得内部和外部实现数据交互。所以需要接口。 比如&…

Spring Boot -- 图书管理系统(登录、展示+翻页、添加/修改图书)

文章目录 一、应用分层二、数据库的设计三、登录功能四、展示列表&#xff08;使用虚构的数据&#xff09;五、翻页 展示功能六、添加图书七、修改图书 一、应用分层 为什么我们需要应用分层&#xff1a;当代码量很多时&#xff0c;将其全部放在一起查找起来就会很麻烦&#…

Docker 可用镜像源

当使用 docker 发现拉取不到镜像时&#xff0c;可以编辑 /etc/docker/daemon.json 文件&#xff0c;添加如下内容&#xff1a; 这文章不涉及政治&#xff0c;不涉及敏感信息&#xff0c;三番五次的审核不通过&#xff0c;一删再删&#xff0c;只好换图片了。 重新加载服务配置…

Zookeeper基础教程

Zookeeper基础教程 资料来源&#xff1a;Zookeeper Tutorial (tutorialspoint.com) zookeeper就是Hadoop生态动物园的管理员 1. Zookeeper-概述 ZooKeeper是一种分布式协调服务&#xff0c;用于管理大型主机集群(large set of hosts)。在分布式环境中协调和管理服务是一个复…