当前位置: 首页 > news >正文

赶紧收藏!2024 年最常见 20道设计模式面试题(七)

上一篇地址:赶紧收藏!2024 年最常见 20道设计模式面试题(六)-CSDN博客

十三、享元模式如何优化资源使用?

享元模式(Flyweight Pattern)是一种结构型设计模式,用于减少创建对象的数量,以减少内存占用和提高性能。这种模式通过共享多于一个对象共同使用的相同状态,来优化资源使用。

享元模式的组成部分:

  1. 享元对象(Flyweight):享元对象是细粒度的,可以被多个客户端共享。
  2. 非享元对象(UnsharedConcreteFlyweight):如果有些状态不能共享,则需要创建非享元对象。
  3. 享元工厂(FlyweightFactory):负责创建和管理享元对象,确保享元对象可以被多个客户端共享。

享元模式的工作原理:

  1. 享元工厂:客户端通过享元工厂请求享元对象。享元工厂首先检查请求的享元对象是否已经存在,如果存在,则返回现有的对象;如果不存在,则创建一个新的对象。
  2. 享元对象:享元对象存储内部状态,这些状态对于所有共享该对象的客户端都是相同的。
  3. 非享元对象:如果享元对象的状态信息有部分是不可以共享的,则需要创建非享元对象来存储这些状态。

享元模式如何优化资源使用:

  • 共享对象:享元模式通过共享尽可能多的对象来减少内存占用。对于具有相同内部状态的对象,享元模式只创建一个实例,然后被多个客户端共享。
  • 减少对象创建:通过享元工厂来控制对象的创建,避免了不必要的对象实例化,从而减少了资源的浪费。
  • 分离内部状态和外部状态:享元模式将对象的内部状态和外部状态分离。内部状态是共享的,而外部状态是特定于每个客户端的,并且不会影响其他客户端。
  • 按需加载:享元模式可以实现按需加载对象,即只有在需要时才创建对象,这有助于减少启动时的资源消耗。

使用场景:

享元模式特别适用于以下情况:

  • 当一个系统有大量相似对象时,这些对象的创建和维护成本很高。
  • 当对象的大部分状态都可以外部化,并且可以由对象的使用者提供时。
  • 当使用简单的工厂模式创建对象开销较大,或者对象的创建和销毁需要花费较多资源时。

代码示例(伪代码):

// 享元接口
interface Flyweight {void operation(String extrinsicState);
}// 具体享元对象
class ConcreteFlyweight implements Flyweight {private intrinsicState; // 内部状态,可以共享public ConcreteFlyweight(int intrinsicState) {this.intrinsicState = intrinsicState;}public void operation(String extrinsicState) {// 操作内部状态和外部状态System.out.println("Operation on intrinsic state: " + intrinsicState + " with extrinsic state: " + extrinsicState);}
}// 享元工厂
class FlyweightFactory {private HashMap<String, Flyweight> flyweights = new HashMap<>();public Flyweight getFlyweight(String key) {if (!flyweights.containsKey(key)) {flyweights.put(key, new ConcreteFlyweight(Integer.parseInt(key)));}return flyweights.get(key);}
}// 客户端代码
FlyweightFactory factory = new FlyweightFactory();
Flyweight flyweightX = factory.getFlyweight("1");
Flyweight flyweightY = factory.getFlyweight("1");flyweightX.operation("Additional information X");
// 输出: Operation on intrinsic state: 1 with extrinsic state: Additional information XflyweightY.operation("Additional information Y");
// 输出: Operation on intrinsic state: 1 with extrinsic state: Additional information Y

在这个示例中,ConcreteFlyweight 是具体的享元对象,它有一个内部状态 intrinsicState,这个状态是共享的。FlyweightFactory 是享元工厂,它管理享元对象的创建和存储。客户端通过工厂来获取享元对象,如果对象已经存在,则工厂返回现有的对象,从而避免了重复创建。通过这种方式,享元模式优化了资源使用,减少了内存占用。

十四、请解释行为型模式中的观察者模式和状态模式的区别。

观察者模式(Observer Pattern)和状态模式(State Pattern)都是行为型设计模式,它们各自解决不同的设计问题,具有不同的结构和用途。下面是两种模式的详细解释和它们之间的主要区别:

观察者模式:

观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。

特点:

  • 主题(Subject)拥有一组观察者(Observer),并在状态改变时通知它们。
  • 观察者模式主要用于实现分布式的事件处理系统。

组成部分:

  • 主题(Subject):维护观察者列表,提供添加、删除和通知观察者的方法。
  • 观察者(Observer):定义了一个更新接口,用于接收主题状态改变的通知。

使用场景:

  • 当一个对象的改变需要同时改变其他对象时,且这些对象可能有很多,而且彼此之间不应该知道对方的存在。

状态模式:

状态模式允许一个对象在其内部状态改变时改变它的行为,看起来好像改变了其类。

特点:

  • 状态模式通过将每个状态封装为一个类,来实现状态的转换逻辑。
  • 状态模式主要用于实现状态机。

组成部分:

  • 状态(State):定义了一个接口,包含一个或多个行为(方法)。
  • 具体状态(Concrete State):实现状态接口,定义具体的状态行为。
  • 上下文(Context):包含一个状态对象引用,负责与状态相关的行为。

使用场景:

  • 当一个对象的行为取决于其状态,且它的状态值在运行时可以改变时。

观察者模式与状态模式的区别:

  1. 目的不同

    • 观察者模式用于对象间的通信,确保当一个对象状态改变时,所有依赖它的对象都会得到通知。
    • 状态模式用于行为随状态改变而改变的场景,实现状态转换逻辑。
  2. 结构不同

    • 观察者模式包含主题和观察者两个主要角色,主题维护观察者列表并负责通知它们。
    • 状态模式包含上下文、状态以及具体状态三个角色,上下文持有状态对象并根据状态改变行为。
  3. 关注点不同

    • 观察者模式关注的是如何在对象间传递消息或事件。
    • 状态模式关注的是如何根据对象的状态改变其行为。
  4. 使用场景不同

    • 观察者模式适用于事件多播问题,如模型-视图-控制器(MVC)架构中的观察者模式。
    • 状态模式适用于状态机问题,如用户界面的不同状态(如正常、暂停、退出)。
  5. 实现方式不同

    • 观察者模式通常通过注册和注销观察者,以及在主题中维护观察者列表来实现。
    • 状态模式通常通过在上下文中维护对当前状态对象的引用,并在状态对象中实现状态转换逻辑来实现。

总结来说,观察者模式和状态模式虽然都是行为型模式,但它们的设计目的、结构组成、关注点和使用场景都有所不同。观察者模式用于对象间的事件通知,而状态模式用于根据状态改变行为。

相关文章:

  • nRF Connect固件升级 OTA DFU Library for Mac and iOS, compatible with nRF5x SoCs
  • AI播客下载:The Gradient-AI前沿见解
  • After Effects 2024 mac/win版:创意视效,梦想起航
  • 持续总结中!2024年面试必问 20 道设计模式面试题(七)
  • ElasticSearch(ES)
  • 基于detours的Windows Hook
  • 每天五分钟计算机视觉:如何在现有经典的卷积神经网络上进行微调
  • 阿里云 app 备案 获取公钥和md5
  • OS复习笔记ch11-3
  • 1. zabbix监控服务器部署
  • 高性价比MOS推荐:惠海HC090N10L,HC025N10L,100V高耐压,12V/24V加湿器和3.7V打火机专用MOS
  • JAVAEE之网络原理(2)_传输控制协议(TCP)的连接管理机制,三次握手、四次挥手,及常见面试题
  • PHP转Go系列 | 字符串的使用姿势
  • 初阶 《数组》 1. 一维数组的创建和初始化
  • Github 2024-06-19 开源项目日报 Top10
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • Javascript Math对象和Date对象常用方法详解
  • mysql常用命令汇总
  • orm2 中文文档 3.1 模型属性
  • storm drpc实例
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 判断客户端类型,Android,iOS,PC
  • 前端学习笔记之观察者模式
  • 设计模式走一遍---观察者模式
  • 实现简单的正则表达式引擎
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • ​Python 3 新特性:类型注解
  • # Kafka_深入探秘者(2):kafka 生产者
  • # Redis 入门到精通(一)数据类型(4)
  • $.proxy和$.extend
  • $forceUpdate()函数
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (精确度,召回率,真阳性,假阳性)ACC、敏感性、特异性等 ROC指标
  • (六)Hibernate的二级缓存
  • (学习日记)2024.02.29:UCOSIII第二节
  • (一)kafka实战——kafka源码编译启动
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (原)Matlab的svmtrain和svmclassify
  • (转)http协议
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .net 设置默认首页
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .NET开源、简单、实用的数据库文档生成工具
  • .NET微信公众号开发-2.0创建自定义菜单
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)
  • @autowired注解作用_Spring Boot进阶教程——注解大全(建议收藏!)
  • [ 英语 ] 马斯克抱水槽“入主”推特总部中那句 Let that sink in 到底是什么梗?
  • [100天算法】-每个元音包含偶数次的最长子字符串(day 53)
  • [2019.2.28]BZOJ4033 [HAOI2015]树上染色
  • [240621] Anthropic 发布了 Claude 3.5 Sonnet AI 助手 | Socket.IO 拒绝服务漏洞
  • [Algorithm][动态规划][简单多状态DP问题][按摩师][打家劫舍Ⅱ][删除并获得点数][粉刷房子]详细讲解
  • [BUUCTF NewStarCTF 2023 公开赛道] week3 crypto/pwn
  • [C/C++]数据结构----顺序表的实现(增删查改)
  • [C++][opencv]基于opencv实现photoshop算法色阶调整
  • [cb]UIGrid+UIStretch的自适应