秋招突击——7/5——设计模式知识点补充——适配器模式、代理模式和装饰器模式

news2025/2/23 10:29:41

文章目录

    • 引言
    • 正文
      • 适配器模式
        • 学习
          • 篮球翻译适配器
        • 面试题
      • 代理模式
        • 学习
        • 面试题
      • 装饰器模式
        • 学习
          • 装饰模式总结
        • 面试题
    • 总结

引言

  • 为了一雪前耻,之前腾讯面试的极其差,设计模式一点都不会,这里找了一点设计模式的面试题,就针对几个常考的设计模式,按照学习 + 面试题 总结的方式,进行学习,今天应该是最后的几个设计模式的学习了。
  • 之前的几个设计模式的学习链接如下
  • 单例模式、工厂模式
  • 简单工厂模式和策略模式

正文

适配器模式

学习
  • 将一个类的接口转换成客户希望的另外一个接口
    • Adapter模式能够使得原本由于接口不兼容而不能一起工作的那些类能够一起工作

具体应用

  • 系统的数据和行为都是正确的,但是接口不符时,应该考虑使用适配器
    • 目的:使控制范围之外的一个原有对象与某个接口匹配
    • 适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境不一致的情况

类型

  • 类适配器(用的少,Java实现不了):
    • 通过多重继承对一个接口与另外一个接口进行匹配
  • 对象适配器

对象适配器的结构图
在这里插入图片描述

  • 具体代码实现样例
    在这里插入图片描述
  • 在上述代码中,
    • target是具体需要调用的目标类
    • Adaptee是需要适配的类,两者无法一块协同工作,彼此相互调用,因为接口不匹配
      在这里插入图片描述
  • 创建一个Adapater对象,继承自目标类target,创建对应需要适配的类,然后调用适配类的方法
  • 客户端只需要调用的适配器就行了,可以使用目标类target的接口调用
篮球翻译适配器
  • 这里截图记录一下,书中举得姚明到NBA打球的例子
    • 翻译者就是适配器,他需要继承并实现球员类,也就是目标类,然后能够调用的需要适配的类的对象。

在这里插入图片描述

面试题

适配器模式了解吗?

  • 在开发中,我们可能会使用两个类进行通信,但是他们之间的接口不同,同时又不方便修改任何一个类的接口,这个时候就需要适配器完成衔接
    • 将一个类的转换成另外一个类的接口,使得原本两个不兼容的接口能够无缝完成对接。

说说适配器的模式的种类以及对应框架流程

  • 类适配器
    • 通过多继承实现,适配器需要同时继承并实现目标类target和被适配的类adaptee

在这里插入图片描述

  • 对象适配器
    • 同各国类对象组合实现适配,继承并实现目标类target,然后调用需要适配的类进行修改。

在这里插入图片描述

适配器有哪些优缺点
优点

  • 提高了类的复用
  • 组合若干关联对象,形成对外统一服务的接口
  • 扩展性和灵活性好

缺点

  • 过多使用适配器会造成代码功能和逻辑意义的混淆
  • 部分语言对继承的限制,之多只能是配一个适配类

代理模式

学习
  • 为其他对象提供一种代理,以控制对这个对象的访问

具体的类图

在这里插入图片描述

  • Subject类代理类和真实类都需要实现和共用的接口

    • 两者同时实现的的话,就能同时调用共同的方法
      在这里插入图片描述
  • RealSubject是真实的类,是实际调用的类,实现了Subject接口

在这里插入图片描述

  • Proxy代理类

    • 保存一个引用可以让代理能够访问实体类的实例对象
    • 提供一个subject接口相同的接口,就可以通过proxy来访问实体类
      在这里插入图片描述
      在这里插入图片描述
  • 客户端代码

    • 客户端要访问实体类,就需要通过代理类,可以通过代理类显示对于实体类的访问

在这里插入图片描述

代理模式的应用

  • 远程代理

    • 为一个对象在不同的地址空间提供局部代表,隐藏一个对象存在于不同地址空间的事实
    • Net技术中的webservice应用,创建web引用的文件
  • 虚拟代理

    • 根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象
    • HTML网页渲染中的图片代理,能够立刻显示文字,但是显示图片需要经过很长时间,没有图片的狂就是虚拟代理,相当于占位符,存储了真实图片的路径和尺寸
  • 安全代理

    • 用来控制真实对象访问时的权限
    • 用于对象应该有不同的访问权限的时候
  • 智能指引

    • 调用真实对象是,代理处理另外一些事
面试题

什么是代理模式

  • 一个中间件,解耦合服务提供者和使用者
    • 使用者通过代理简洁访问服务提供者,便于后者封装和控制
    • 结构性模式

在这里插入图片描述

静态代理和动态代理的区别
静态代理

  • 特征
    • 在编译期间就已经确定,需要手动编写代理类,代理类和目标类实现相同的接口
    • 代理类会包含对目标对象的引用,并在代理方法中调用目标对象的相应方法
  • 优点
    • 结构清晰,容易理解和维护
    • 编译时即可发现代码错误
  • 缺点
    • 接口方法多,代理类需要实现多有的方法,代码冗余
    • 每次新增都需要修改接口和方法,修改代理类,维护成本高
// 接口
public interface Service {
    void perform();
}

// 目标类
public class RealService implements Service {
    @Override
    public void perform() {
        System.out.println("Performing service...");
    }
}

// 代理类
public class StaticProxyService implements Service {
    private RealService realService;

    public StaticProxyService(RealService realService) {
        this.realService = realService;
    }

    @Override
    public void perform() {
        System.out.println("Static Proxy: Before performing service...");
        realService.perform();
        System.out.println("Static Proxy: After performing service...");
    }
}

// 使用代理
public class Main {
    public static void main(String[] args) {
        RealService realService = new RealService();
        StaticProxyService proxyService = new StaticProxyService(realService);
        proxyService.perform();
    }
}

动态代理

  • 特征
    • 在运行期间动态 生成
    • 通过反射机制生成代理类,不需要手动编写代理类
    • Java中通过reflect.proxy实现动态代理
  • 优点
    • 代理类不需要手动编写,减少代码量和维护成本
    • 灵活对接口中方法进行增强
  • 缺点
    • 使用了反射机制,性能低于静态代理
    • 动态代理代码逻辑复杂,理解调试困难

下面的代码确实复杂,没看懂

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 接口
public interface Service {
    void perform();
}

// 目标类
public class RealService implements Service {
    @Override
    public void perform() {
        System.out.println("Performing service...");
    }
}

// 动态代理类
public class DynamicProxyHandler implements InvocationHandler {
    private Object target;

    public DynamicProxyHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Dynamic Proxy: Before performing service...");
        Object result = method.invoke(target, args);
        System.out.println("Dynamic Proxy: After performing service...");
        return result;
    }
}

// 使用代理
public class Main {
    public static void main(String[] args) {
        RealService realService = new RealService();
        Service proxyService = (Service) Proxy.newProxyInstance(
            realService.getClass().getClassLoader(),
            realService.getClass().getInterfaces(),
            new DynamicProxyHandler(realService)
        );
        proxyService.perform();
    }
}

装饰器模式

学习

装饰模式定义

  • 动态给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。

装饰模式的类图

在这里插入图片描述

  • 在上述结构图中,各部分说明如下
    • Component:定义一个对象接口,给这些对象动态添加职责、方法和对象
    • ConcreteComponet:定义一个具体的类,可以给这个对象添加一些职责
    • Decorator:装饰抽象类,继承了Componet,从外类扩展Component类的功能,对于Component来说,无需知道Decorator的存在,

感觉这里比较费劲,还得看一下这个代码是怎么实现的

Component抽象类

  • 这个是具体需要执行或者说进行装饰的抽象类
    在这里插入图片描述
    ConcreteComponent类
  • 是对上一个类的具体实现,也就是具体操作对象

在这里插入图片描述
Decorator类

  • 也是一个抽象类,继承component类,需要传入一个component,然后执行component的具体的方法

在这里插入图片描述
ConcreteDecoratorA

  • 这个是继承了Decorator类的具体的类,用来接受具体的component进行装饰,增加额外的操作
  • 相当于,这里增加了一个套壳

在这里插入图片描述客户端代码

  • 这里需要创建对应需要修改的具体的组件对象以及抽象类对象,然后创建进行组合

在这里插入图片描述
本质

  • 使用SetComponent来对对象进行包装,
    • 每一个装饰对象的实现就和如何使用这个对象离开了,每一个装饰对象只关心自己的功能,不需要关心如何添加到对项链中
装饰模式总结

装饰模式
* 为已有功能动态添加更多功能的一种方式

对比原始方法

  • 如果直接在原始的类中直接增加新的功能,会让原始的类更加复杂,而且添加的功能,一般是在某种特定情况下,才会执行的特殊行为的需要,并没有普遍性,所以不需要添加。

解决问题

  • 把每一个装饰的功能,放在单独的类中,让这个类包装她所需要装饰的对象,
  • 针对执行特殊行为时,客户代码就可以在运行时,有选择地、按顺序地用装饰功能包装对象了。

优点

  • 将类中的装饰功能,从类中搬移出去,简化原有的类
面试题

什么时装饰器模式

  • 对现有的类对象进行包裹和封装,以期望不改变类对象及其类定义的情况下,为对象添加额外的功能
  • 对象结构性模式
  • 通过调用被包裹后的对象完成功能添加,不直接修改现有对象的行为

装饰器模式应用场景

  • 希望在不修改代码的情况下,使用对象,并且要求在运行时,为对象新增额外的行为,使用装饰模式
  • 使用继承扩展对象行为的方案难以实现时,使用装饰器模式进行扩展
  • 如果类已经用final修饰,如果要复用这个类对象,可以使用修饰器

总结

  • 一下子又让我紧张了,下周一字节面试,我觉得基本上没戏,而且失去杭州,不过要是有机会,还是回去的,周末回来一次,也是不错的。想想就好了,我就准备了,一个半月,去面试,能进真的烧高香了。
  • 现在是四点半,晚上就好好看看项目吧,准备一下简历,然后准备投递秋招的提前批了,目前关于设计模式的基本上看完了,明天可能要在收个尾,还剩下责任链模式和观察者模式,其他的基本上都不考。
  • 加油!

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

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

相关文章

加密(3)非对称加密

一、介绍 1、概念 非对称加密,又称现代加密算法,非对称加密是计算机通信安全的基石,保证了加密数据不会被破解。加密和解密使用的是两个不同的密钥,这种算法叫作非对称加密算法。 2、示例 首先生成密钥对, 公钥为(5,14)&#…

docker中实现多机redis主从集群

redis主从集群是每个使用redis的小伙伴都必需知道的,那如何在docker中快速配置呢?这篇来教你快速上手,跟着复制完全就能用!! 1. 前置准备 1.1 docker安装 以防有小伙伴没预先安装docker,这里提供安装步骤…

小白学python(第五天)if语句的拓展

上次因为个人原因才匆忙讲解完python的顺序条件,导致if语句中有部分知识点没讲完,那么本篇文章将带大家继续学习python的if语句。 前情回顾 上集说到 if语句的模板,并且让大家注意了if后面直接跟条件无需加括号以及条件后冒号也不能忘&…

Android Camera2 集成人脸识别算法

这可能是全网唯一一篇介绍Android Camera2接口集成人脸算法的文章了~ 写在前面: 说起人脸识别,相信大家都不会感到陌生,在我们平时的工作生活中,人脸打卡、刷脸支付等等已经是应用的非常广泛了,人脸识别也给我们的生活…

如何给gitlab其他访问者创建账号并增加权限

嗨,今天创建了项目之后,我想把项目链接发送给其他人,让他下载这个项目,结果发现对方打开显示登录的界面,没错,他要想使用这个git下载项目,首先他的有一个git账号 接下来我找有权限的相关人员给他…

Pseudo-Label : The Simple and Efficient Semi-Supervised Learning Method--论文笔记

论文笔记 资料 1.代码地址 https://github.com/iBelieveCJM/pseudo_label-pytorch 2.论文地址 3.数据集地址 论文摘要的翻译 本文提出了一种简单有效的深度神经网络半监督学习方法。基本上,所提出的网络是以有监督的方式同时使用标记数据和未标记数据来训练的…

机器学习——决策树及其可视化

1、决策树概念 顾名思义,决策树是利用数据结构中树结构来进行判断,每一个结点相当于一个判断条件,叶子结点即是最终的类别。以鸢尾花为例,可以得到如下的决策树: 2、决策树分类的依据是什么? 根据前面分…

MySQL---事务管理

1.关于事务 理解和学习事务,不能只站在程序猿的角度来理解事务,而是要站在使用者(用户)的角度来理解事务。 比如支付宝转账,A转了B100块前,在程序猿的角度来看,是两条update操作,A …

电源设计技巧:DDR内存电源

CMOS逻辑系统的功耗主要与时钟频率、系统内各栅极的输入电容以及电源电压有关。器件形体尺寸减小后,电源电压也随之降低,从而在栅极层大大降低功耗。这种低电压器件拥有更低的功耗和更高的运行速度,允许系统时钟频率升高至千兆赫兹级别。在这…

非参数检测1——概述

在绝大多数的检测理论研究中,都着重于设计最优的检测器,最优检测器拥有最优的性能,但需要知道对输入信号和噪声的完整的统计学描述,这在实际应用中很可能无法实现。 实际情况: 设计检测系统时,无法得知完…

Kafka的简介、架构、安装使用、生产者、消费者、高吞吐、持久化及与Flume整合

Apache Kafka是一个分布式流处理平台,最初由LinkedIn公司开发,后来成为Apache软件基金会的一个顶级项目。Kafka主要用于构建实时数据管道和流处理应用程序。Kafka广泛应用于日志聚合、实时分析、事件源、流处理等场景。它与各种数据处理框架和数据库集成…

纯javascript实现图片批量压缩打包zip下载后端ThinkPHP多国语言切换国际站

最近在做一个多国语言的工具站,需要实现多国语言切换,说到多国语言站,肯定是有2种方式,第一是子域名,第二就是子目录。根据自己的需要来确定。 后台配置如下: 前台显示: 前端纯javascript实现…

VS code修改底部的行号的状态栏颜色

VSCode截图 相信很多小伙伴被底部的蓝色状态栏困扰很久了 处理的方式有两种: 1、隐藏状态栏 2、修改其背景颜色 第一种方法大伙都会,今天就使用第二种方法。 1、点击齿轮进入setting 2、我现在用的新版本,设置不是以前那种json格式展示&…

im即时通讯哪家好?WorkPlus im即时通讯集成底座为企业保驾护航

在当今数字化时代,即时通讯是企业内部沟通和协作的重要工具,提高工作效率和团队协作效果。在众多IM即时通讯提供商中,WorkPlus作为一家具有独特优势的企业IM即时通讯集成底座,为企业提供了全面的功能和安全保障,为企业…

一道有意思的简单题 [NOIP2010 普及组] 接水问题

题目&#xff1a; 题解&#xff1a; 每一次新来的同学的接水时间都加在现在已有的水龙头中接水时间最短的&#xff0c;总时间就为n次操作后水龙头中接水时间的最长值。 #include<bits/stdc.h> using namespace std; multiset<int>s;int main(){int n,m;scanf(&qu…

Linux基础指令及mysql(DQL)

[rootcentos ~]# echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/export/server/jdk/bin:/root/binls在/usr/bin/路径下 [rootcentos ~]# which ls alias lsls --colorauto/usr/bin/lschmod ux,gx,o-r work.txt 可以对文件的权限进行修改。 sudo chown 修…

泛微开发修炼之旅--32ecology对接海康威视综合安防管理系统,人脸识别机器数据同步代码方案及源码

文章链接&#xff1a;32ecology对接海康威视综合安防管理系统&#xff0c;人脸识别机器数据同步代码方案及源码

电脑硬盘分区的基本步骤(2个实用的硬盘分区方法)

在现代计算机中&#xff0c;硬盘分区是非常重要的一步。无论是新硬盘的初始化&#xff0c;还是重新组织现有硬盘&#xff0c;分区都是必不可少的操作。本文将详细介绍电脑硬盘分区的基本步骤&#xff0c;帮助您更好地管理和利用硬盘空间。 文章开始&#xff0c;我们先简单说一…

CSS实现图片裁剪居中(只截取剪裁图片中间部分,图片不变形)

1.第一种方式&#xff1a;&#xff08;直接给图片设置&#xff1a;object-fit:cover;&#xff09; .imgbox{width: 100%;height:200px;overflow: hidden;position: relative;img{width: 100%;height: 100%; //图片要设置高度display: block;position: absolute;left: 0;right…

JavaDS预备知识

集合框架 Java 集合框架 Java Collection Framework &#xff0c;又被称为容器 container &#xff0c;是定义在 java.util 包下的一组接口 interfaces和其实现类 classes 。 其主要表现为将多个元素 element 置于一个单元中&#xff0c;对数据进行创建(Create)、读取(Retrieve…