持续总结中!2024年面试必问 20 道设计模式面试题(四)

2024-06-19 00:28

本文主要是介绍持续总结中!2024年面试必问 20 道设计模式面试题(四),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

上一篇地址:持续总结中!2024年面试必问 20 道设计模式面试题(三)-CSDN博客

七、观察者模式(Observer Pattern)是如何工作的?

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

观察者模式的主要组件:

  1. 主题(Subject)

    • 主题是观察者模式的核心,它维护了一组观察者对象的引用,并提供接口用于注册(attach)、移除(detach)和通知(notify)观察者。
  2. 观察者(Observer)

    • 观察者是一个接口,定义了观察者对象必须实现的更新接口,以便在主题状态改变时得到通知。
  3. 具体主题(ConcreteSubject)

    • 具体主题实现了主题接口,存储状态信息,并提供方法供观察者注册和移除自己。当状态发生改变时,它会自动通知所有注册的观察者。
  4. 具体观察者(ConcreteObserver)

    • 具体观察者实现了观察者接口,根据主题的当前状态更新自己的状态。通常包含一个指向具体主题的引用,但这个引用不是必需的,取决于具体的实现。
  5. 客户端(Client)

    • 客户端代码创建并配置了具体主题和具体观察者,将观察者注册到主题上,并触发事件以演示观察者模式的工作。

观察者模式的工作原理:

  1. 注册观察者:具体观察者对象通过调用具体主题的注册方法将自己注册为观察者。

  2. 状态变更:当具体主题的状态发生变化时,它会调用所有注册观察者的更新方法。

  3. 通知观察者:具体主题通过调用观察者的更新方法来通知它们状态已经改变,通常传递一些必要的信息,如变化的状态本身或一个事件对象。

  4. 更新状态:具体观察者接收到通知后,根据传递的信息更新自己的状态。

示例代码(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) {observers.remove(o);}public void notifyObservers() {for (Observer observer : observers) {observer.update(state);}}public void setState(String state) {this.state = state;notifyObservers();}
}// 具体观察者
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("Received update: " + message);}
}// 客户端代码
public class ObserverPatternDemo {public static void main(String[] args) {ConcreteSubject subject = new ConcreteSubject();new ConcreteObserver(subject); // 注册观察者subject.setState("State 1"); // 状态变更,通知观察者subject.setState("State 2"); // 再次状态变更}
}

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

观察者模式使得对象间的耦合度降低,当一个对象的状态变化时,依赖于它的对象会自动更新,而无需直接调用这些对象的方法。这使得系统更加灵活和易于维护。

八、装饰器模式(Decorator Pattern)和适配器模式有何不同?

装饰器模式(Decorator Pattern)和适配器模式(Adapter Pattern)虽然都是结构型设计模式,但它们解决的问题和设计目的是不同的。以下是两种模式的主要区别:

目的不同:

  • 适配器模式 主要用于使不兼容的接口能够一起工作。它通常用于将一个类的接口转换成客户端期望的另一个接口,从而让原本由于接口不兼容而不能一起工作的类可以协同工作。

  • 装饰器模式 主要用于动态地给一个对象添加额外的职责。它允许用户在不修改原始对象的基础上,通过添加装饰类来扩展对象的功能。

结构不同:

  • 适配器模式 包含以下角色:

    • 目标接口(Target):希望适配的接口。
    • 适配者(Adaptee):需要适配的类。
    • 适配器(Adapter):通过在内部包装一个适配者对象,把源接口转换成目标接口。
  • 装饰者模式 包含以下角色:

    • 抽象组件(Component):定义了被装饰接口。
    • 具体组件(ConcreteComponent):实现了抽象组件的具体类。
    • 抽象装饰者(Decorator):抽象类,实现了装饰接口,并持有一个装饰接口的引用。
    • 具体装饰者(ConcreteDecorator):实现抽象装饰者,添加额外的职责。

使用场景不同:

  • 适配器模式 常用于以下场景:

    • 需要将一个已有的类集成到一个新系统中,但接口不兼容。
    • 需要复用一些已有的类,但这些类的接口与新系统的接口不一致。
  • 装饰者模式 常用于以下场景:

    • 需要动态地给对象添加职责,同时希望避免使用继承带来的耦合。
    • 需要通过一种灵活的方式来扩展对象的功能,同时保持对象的开放封闭原则。

行为不同:

  • 适配器模式 通常只关注于接口的转换,不涉及对象功能的扩展。

  • 装饰者模式 允许通过多个装饰者的嵌套使用,来逐步添加多个职责,形成一种链式结构。

示例:

  • 适配器模式示例:假设有一个第三方音乐播放器类ThirdPartyMusicPlayer,它有一个playMusic()方法。你的系统需要一个play()方法的接口。可以创建一个适配器MusicPlayerAdapter,它实现了play()方法,内部调用ThirdPartyMusicPlayerplayMusic()方法。

  • 装饰者模式示例:假设有一个Coffee类,有一个cost()方法返回咖啡的价格。为了添加如加糖、加牛奶等额外服务,可以创建一个装饰者CoffeeDecorator,它持有一个Coffee对象的引用,并在调用cost()方法时添加额外的费用。

总结来说,适配器模式主要用于接口转换,而装饰者模式主要用于对象功能的动态扩展。两者虽然都可以用于复用已有的代码,但它们关注的问题和实现方式是不同的。

这篇关于持续总结中!2024年面试必问 20 道设计模式面试题(四)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1073484

相关文章

Python中实现进度条的多种方法总结

《Python中实现进度条的多种方法总结》在Python编程中,进度条是一个非常有用的功能,它能让用户直观地了解任务的进度,提升用户体验,本文将介绍几种在Python中实现进度条的常用方法,并通过代码... 目录一、简单的打印方式二、使用tqdm库三、使用alive-progress库四、使用progres

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)

《Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)》:本文主要介绍Python基于火山引擎豆包大模型搭建QQ机器人详细的相关资料,包括开通模型、配置APIKEY鉴权和SD... 目录豆包大模型概述开通模型付费安装 SDK 环境配置 API KEY 鉴权Ark 模型接口Prompt

Java向kettle8.0传递参数的方式总结

《Java向kettle8.0传递参数的方式总结》介绍了如何在Kettle中传递参数到转换和作业中,包括设置全局properties、使用TransMeta和JobMeta的parameterValu... 目录1.传递参数到转换中2.传递参数到作业中总结1.传递参数到转换中1.1. 通过设置Trans的

C# Task Cancellation使用总结

《C#TaskCancellation使用总结》本文主要介绍了在使用CancellationTokenSource取消任务时的行为,以及如何使用Task的ContinueWith方法来处理任务的延... 目录C# Task Cancellation总结1、调用cancellationTokenSource.

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题

题库来源:安全生产模拟考试一点通公众号小程序 2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题是由安全生产模拟考试一点通提供,流动式起重机司机证模拟考试题库是根据流动式起重机司机最新版教材,流动式起重机司机大纲整理而成(含2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题参考答案和部分工种参考解析),掌握本资料和学校方法,考试容易。流动式起重机司机考试技

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业