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

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

五、适配器模式是如何工作的?请举例说明。

适配器模式(Adapter Pattern)是一种常用的设计模式,属于结构型模式之一。它主要用于解决两个不兼容接口之间的问题,使得原本因接口不兼容而不能一起工作的类可以协同工作。适配器模式通常包含以下几个角色:

  1. 目标(Target):定义客户端使用的特定领域相关的接口。
  2. 适配者(Adaptee):一个已经存在的类,需要适配。
  3. 适配器(Adapter):通过在内部包装一个Adaptee对象,把源接口转换成目标接口。

工作原理:

适配器模式的工作原理是创建一个中间层(适配器),这个中间层将不兼容的接口转换成客户端期望的接口。适配器模式让原本因接口不兼容而不能一起工作的类可以协同工作。

举例说明:

假设我们有一个第三方库,它提供了一个MediaPlayer接口,该接口有一个play方法,用于播放音频。但是,我们手头有一个旧的音频播放类OldAudioPlayer,它有一个playAudio方法,而不是play方法。现在,我们想要使用OldAudioPlayer来播放音频,但是它不符合MediaPlayer接口的要求。

为了解决这个问题,我们可以创建一个适配器AudioPlayerAdapter,它实现了MediaPlayer接口,并在其内部持有一个OldAudioPlayer的实例。当调用AudioPlayerAdapterplay方法时,它会调用内部OldAudioPlayerplayAudio方法,从而实现接口的适配。

// 目标接口
interface MediaPlayer {void play();
}// 旧的音频播放类
class OldAudioPlayer {public void playAudio() {System.out.println("Playing audio using OldAudioPlayer");}
}// 适配器类
class AudioPlayerAdapter implements MediaPlayer {private OldAudioPlayer oldAudioPlayer;public AudioPlayerAdapter(OldAudioPlayer oldAudioPlayer) {this.oldAudioPlayer = oldAudioPlayer;}@Overridepublic void play() {oldAudioPlayer.playAudio();}
}// 客户端代码
public class Client {public static void main(String[] args) {OldAudioPlayer oldAudioPlayer = new OldAudioPlayer();MediaPlayer mediaPlayer = new AudioPlayerAdapter(oldAudioPlayer);mediaPlayer.play(); // 通过适配器调用旧的播放方法}
}

在这个例子中,AudioPlayerAdapter充当了适配器的角色,它使得OldAudioPlayer能够以MediaPlayer接口的形式被使用。这样,我们就可以在不修改原有代码的情况下,让旧的类与新的接口兼容。

六、什么是观察者模式?它在实际应用中有哪些用途?

观察者模式(Observer Pattern)是一种行为设计模式,它定义了对象间的一种一对多的依赖关系,使得当一个对象状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式通常用于实现分布式事件处理系统。

观察者模式的主要角色:

  1. 主题(Subject):也称为被观察者,它维护一组观察者,提供注册、注销和通知观察者的方法。
  2. 观察者(Observer):定义了一个更新接口,用于在得到主题通知时更新自己。
  3. 具体主题(ConcreteSubject):实现抽象主题中的方法,维护当前状态,当状态发生改变时,通知所有观察者。
  4. 具体观察者(ConcreteObserver):实现观察者接口,存储与主题相关的状态,实现更新接口。

工作原理:

  1. 观察者模式中的主题维护一个观察者列表。
  2. 当主题的状态发生变化时,它会通知列表中的所有观察者。
  3. 观察者接收到通知后,会调用自己的更新方法,以响应主题状态的变化。

实际应用中的用途:

  1. 用户界面(UI)更新:在图形用户界面中,当模型数据发生变化时,界面需要相应地更新。观察者模式可以用于实现数据和视图之间的自动同步。

  2. 事件监听:在事件驱动的系统中,事件的发布者(主题)可以注册多个监听者(观察者),当事件发生时,所有监听者都会收到通知。

  3. 消息推送系统:在消息推送系统中,服务端(主题)可以向多个客户端(观察者)推送消息,当有新消息时,所有客户端都会收到通知。

  4. 股票市场监控:在股票交易系统中,股票价格的变化可以作为主题,而投资者、交易算法等可以作为观察者,当股票价格变动时,所有相关方都会得到通知。

  5. 网络通信:在网络通信中,服务器(主题)可以向多个客户端(观察者)发送数据更新,当数据发生变化时,所有客户端都会收到更新。

示例代码(Java):

// 观察者接口
interface Observer {void update(String message);
}// 主题接口
interface Subject {void registerObserver(Observer o);void removeObserver(Observer o);void notifyObservers();
}// 具体主题
class ConcreteSubject implements Subject {private List<Observer> observers = new ArrayList<>();private String state;public void registerObserver(Observer o) {observers.add(o);}public void removeObserver(Observer o) {int i = observers.indexOf(o);if (i >= 0) {observers.remove(i);}}public void notifyObservers() {for (Observer observer : observers) {observer.update(state);}}public void setState(String state) {this.state = state;notifyObservers();}public String getState() {return state;}
}// 具体观察者
class ConcreteObserver implements Observer {private ConcreteSubject subject;public ConcreteObserver(ConcreteSubject subject) {this.subject = subject;subject.registerObserver(this);}@Overridepublic void update(String message) {System.out.println("Observer: " + message);}
}// 客户端代码
public class Client {public static void main(String[] args) {ConcreteSubject subject = new ConcreteSubject();ConcreteObserver observer1 = new ConcreteObserver(subject);ConcreteObserver observer2 = new ConcreteObserver(subject);subject.setState("State1");subject.removeObserver(observer1);subject.setState("State2");}
}

在这个示例中,ConcreteSubject是具体的主题,它维护了一个观察者列表,并在状态变化时通知所有观察者。ConcreteObserver是具体观察者,实现了Observer接口,当接收到通知时,会打印消息。客户端代码创建了主题和观察者,并演示了状态更新和观察者注册/注销的过程。

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

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

相关文章

常见的浏览器内核有哪些,对浏览器内核的理解。

目录 Trident内核&#xff08;也被称为MSHTML或IE内核&#xff09;&#xff1a; Gecko内核&#xff1a; Webkit内核&#xff1a; Blink内核&#xff1a; Presto内核&#xff1a; 归纳&#xff1a; 最主流的浏览器内核&#xff1a; 对浏览器内核的深入理解&#xff1a; T…

std::shared_mutex 举例

std::shared_mutex 是 C17 引入的一个类型&#xff0c;它允许多个线程同时获取共享锁&#xff08;shared lock&#xff09;&#xff0c;但只允许一个线程独占锁&#xff08;exclusive lock&#xff09;。这样&#xff0c;多个线程可以并发地读取共享数据&#xff0c;但在写入数…

Mysql5.7安装教程(详细图解教程)_mysql5.7下载

本文讲解的是mysql5.7安装包、mysql5.7下载、mysql5.7安装配置教程、离线安装mysql5.7。MySQL 5.7 是 MySQL 数据库的一个重要版本&#xff0c;它引入了许多新特性和改进&#xff0c;旨在提高性能、安全性和易用性。 MySQL 5.7 在所有负载模型上都有显著的性能改进&#xff0c…

简述一下你对html语义化的理解

HTML语义化是指使用HTML标签来明确表示网页内容的含义和结构&#xff0c;而不是仅仅使用它们来呈现样式或布局。以下是关于HTML语义化的分点概述&#xff1a; 增强可读性&#xff1a; 语义化的HTML代码更易于阅读和理解&#xff0c;因为标签的选择反映了内容的意义。这不仅方便…

头歌资源库(10)拼数字

一、 问题描述 二、算法思想 初始化一个长度为10的数组count&#xff0c;用于记录卡片中每个数字的数量。 从1开始依次尝试拼出正整数&#xff0c;直到无法拼出下一个数为止。 对于每个尝试拼出的正整数&#xff0c;遍历其每一位的数字&#xff0c;检查该数字在count中是否还…

中国电力年鉴(2004-2023年)

数据年限&#xff1a;2004-2023 数据格式&#xff1a;pdf、excel 数据内容&#xff1a;电力年鉴收录了我国电力行业年度统计数据&#xff0c;是较为全面反映我国电力企业生产运行情况的统计资料书。以2023年为例&#xff0c;全书共分为五个部分&#xff1a;第一部分为基本数据&…

嵌入式中间件_2.嵌入式中间件的分类

1.中间件的分类 中间件的范围十分广泛&#xff0c;针对不同的应用需求涌现出了多种各具特色的中间件产品。因此&#xff0c;在不同的角度或不同的层次上&#xff0c;对中间件的分类也会有所不同。 根据IDC在1998年对中间件进行的分类&#xff0c;把中间件分为终端仿真/屏幕转换…

面试题——Nginx

1.Nginx是什么&#xff1f; 是一个高性能的Web服务器和反向代理服务器&#xff0c;也可以作为静态文件的缓存服务器&#xff0c;也能够进行负载均衡。 2.Nginx的作用&#xff1f; 1.反向代理&#xff1a;将多台服务器代理为一台服务器。客户端不了解底层服务端。 2.负载均衡…

eclipse导入Tomcat9源码

环境准备 下载Tomcat源码 https://github.com/apache/tomcat/tagsJDK版本 Tomcat9要求JDK17以上版本 https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.htmlAnt安装 https://ant.apache.org/bindownload.cgi我这里装的是apache-ant-1.10.14版本 …

CLIP模型调用的一段代码及解释

代码示例 from transformers import CLIPProcessor, CLIPModel# 加载预训练的CLIP模型和处理器 model CLIPModel.from_pretrained("openai/clip-vit-base-patch32") processor CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")# 显示图像…

从0到1,揭秘AI产品经理的高薪秘诀,转型之路与实战资源全解析

前言 随着算法模型的日益精进、计算能力的显著提升以及海量数据的积累&#xff0c;人工智能领域正以前所未有的速度蓬勃发展。 在国家政策的积极推动、社会资本的强劲注入下&#xff0c;人工智能产业正处于技术快速进步的黄金时期&#xff0c;其影响力广泛渗透至教育智能化、…

Day54 代码随想录打卡|二叉树篇---二叉搜索树的最近公共祖先

题目&#xff08;leecode T235&#xff09;&#xff1a; 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表示为一个结点 x&#xff0c;满足 x 是 p、q 的祖…

Nginx负载均衡之负载均衡策略

负载均衡技术是将大量的客户端请求通过特定的策略分配到集群中的节点&#xff0c;实现快速响应的应用技术。在应对高并发的应用请求时&#xff0c;单节点的应用服务计算能力有限&#xff0c;无法满足客户端的响应需求&#xff0c;通过负载均衡技术&#xff0c;可以将请求分配到…

DAY 45 企业级虚拟化技术KVM

企业级虚拟化技术KVM 1.kvm是什么 kernel virtualization machine 内核虚拟机 qemu的二次开发 软件全拼 qemu-kvm kvm virtulbox ovm vmware vsphere套件&#xff08;vmawre-esxi&#xff09; microsoft hyper-V 2.什么是虚拟化 资源利用 资源隔离 虚拟化管理&…

CleanMyMac X for Mac系统优化垃圾清理软件卸载 工具(小白轻松上手,简单易学)

Mac分享吧 文章目录 效果一、准备工作二、开始安装1、双击运行软件&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、启动台显示软件图标&#xff0c;表示安装成功 三、运行测试1、打开软件&#xff0c;配置2、授权&#xff0c;允许完全磁盘访问 安装完成&a…

驱动、BSP、HAL三者的区别和联系

目录 引言 一、驱动&#xff08;Driver&#xff09; 二、板级支持包&#xff08;BSP, Board Support Package&#xff09; 三、硬件抽象层&#xff08;HAL, Hardware Abstraction Layer&#xff09; 四、区别与联系 五、总结 引言 驱动&#xff08;Driver&#xff09;、板…

正规式理解

正规式&#xff08;Regular Expression&#xff09;是一种用于描述、识别字符串集合的模式&#xff08;尤其是正则语言&#xff09;的序列表达式。在软件设计中&#xff0c;正规式被广泛用于文本处理、搜索和替换、数据验证等场景。以下是对正规式的基本理解&#xff1a; 1. *…

django filter 数据 Response返回

在Django中&#xff0c;你可以使用Django的filter()方法来筛选查询集(QuerySet)&#xff0c;并将结果返回给客户端。以下是一个简单的例子&#xff0c;展示了如何在Django视图中筛选数据&#xff0c;并将结果以JSON的形式返回给客户端。 首先&#xff0c;确保你有一个Django模…

vue3 defineComponent + 渲染函数h + 全局注册​

defineComponent 是 Vue 3 中的一个函数&#xff0c;用于定义一个组件。它是 Vue 3 的组合式 API 的一部分&#xff0c;提供了一种更加灵活和组织化的方式来定义组件。在 Vue 2 中&#xff0c;我们通常使用一个对象来定义组件&#xff0c;而在 Vue 3 中&#xff0c;defineCompo…

赶走异味保持清香,何浩明净味爽身香体膏

夏天来了&#xff0c;大家都想要清清爽爽的出门&#xff0c;但是汗味、狐臭这些小问题都在所难免&#xff0c;总要想办法应对&#xff0c;我目前用的是一款香体膏&#xff0c;它不仅能赶走那些让人尴尬的异味&#xff0c;还能让我们享受一整天的清新自在。 我用的这款叫做何浩明…