设计模式之适配器与装饰器

目录

适配器模式

简介

角色

使用

优缺点

使用场景

装饰器模式

简介

优缺点

模式结构

使用

使用场景


适配器模式

简介

允许将不兼容的对象包装成一个适配器类,使得其他类可以通过适配器类与原始对象进行交互,从而提高兼容性

角色

目标角色:该角色定义把其他类转换为何种接口,也就是我们的期望接口

源角色:你想把谁转换成目标角色,这个“谁”就是源角色,它是已经存在的、运行良好的类或对象

适配器角色:适配器模式的核心角色,其他两个角色都是已经存在的角色,而适配器角色是需要新建立的,它的职责非常简单:通过继承或是类关联的方式把源角色转换为目标角色

使用

1.定义目标接口:创建一个目标接口,这个接口定义了客户端所期望的功能。

2.创建原始类:客户端原始功能

3.创建适配器类:创建一个适配器类,该类实现了目标接口,同时包装了不兼容的原始对象,使得客户端可以通过目标接口与原始对象进行交互

4.使用目标接口:客户端代码使用目标接口与适配器进行交互

// 目标接口  
interface Target {  void request();  
}  // 原始类  
class Adaptee {  void specificRequest() {  System.out.println("Adaptee's specific request.");  }  
}  // 适配器类  
class Adapter implements Target {  private Adaptee adaptee;  public Adapter(Adaptee adaptee) {  this.adaptee = adaptee;  }  @Override  public void request() {  adaptee.specificRequest();  }  
}  // 客户端代码  
public class Client {  public static void main(String[] args) {  Adaptee adaptee = new Adaptee();  Target target = new Adapter(adaptee);  target.request();  }  
}

        目标接口Target,它定义了一个request方法。我们还有一个原始类Adaptee,它有一个名为specificRequest的方法。我们的适配器类Adapter实现了目标接口,并且包装了原始类的specificRequest方法。在客户端代码中,我们创建了一个原始类的实例和一个适配器类的实例,然后将适配器类的实例传递给目标接口的引用。当我们调用目标接口的request方法时,实际上是适配器类在调用原始类的specificRequest方法

优缺点

优点:

        1.能提高类的透明性和复用,现有的类复用但不需要改变。

        2.目标类和适配器类解耦,提高程序的扩展性。

        3.在很多业务场景中符合开闭原则

缺点:

        1.适配器编写过程需要全面考虑,可能会增加系统的复杂性

        2.增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱

使用场景

        1.一个类的接口转换成期望的另一个接口,使不能兼容的两个类一起工作

        2.想要创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类协同工作

        3.在软件维护期间,由于不同产品或不同厂家造成功能类似而接口不相同的情况,可以通过适配器模式来解决

        使用适配器模式可以降低不同组件之间的耦合度,提高系统的可扩展性和可维护性。同时,适配器模式还可以解决不同系统之间的接口不兼容问题

装饰器模式

简介

        在不改变现有对象结构下,动态的给对象添加一些功能

优缺点

优点

        1.装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用

        2.通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果

        3.装饰器模式完全遵守开闭原则

缺点

        装饰器模式会增加许多子类,过度使用会增加程序得复杂性

模式结构

角色:

        抽象构件角色:定义一个抽象接口以规范准备接收附加责任的对象

        具体构件角色:实现抽象构件,通过装饰角色为其添加一些职责

        抽象装饰角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能

        具体装饰角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任

结构图:

使用

1.创建接口

public interface Shape {  double getArea();  
}

2.接口具体实现类

public class Rectangle implements Shape {  private double length;  private double width;  public Rectangle(double length, double width) {  this.length = length;  this.width = width;  }  @Override  public double getArea() {  return length * width;  }  
}

3.创建抽象装饰器

public abstract class ShapeDecorator implements Shape {  protected Shape decoratedShape;  public ShapeDecorator(Shape shape) {  this.decoratedShape = shape;  }  @Override  public double getArea() {  return decoratedShape.getArea();  }  
}

4.创建具体装饰器

public class RectangleWithBorder extends ShapeDecorator {  private double borderWidth;  public RectangleWithBorder(Shape shape, double borderWidth) {  super(shape);  this.borderWidth = borderWidth;  }  @Override  public double getArea() {  return decoratedShape.getArea() + borderWidth * decoratedShape.getArea();  }  
}

5.使用

public class Main {  public static void main(String[] args) {  Shape rectangle = new Rectangle(5, 5);  Shape rectangleWithBorder = new RectangleWithBorder(rectangle, 1); // 给矩形添加边框宽度为1的装饰器  System.out.println("Rectangle area: " + rectangle.getArea()); // 输出:Rectangle area: 25.0  System.out.println("Rectangle with border area: " + rectangleWithBorder.getArea()); // 输出:Rectangle with border area: 27.0  }  
}

使用场景

1.扩展功能:当您想要扩展一个类的功能时,可以使用装饰器模式来添加新的责任,而不需要修改原有类的代码。这使得代码更加灵活,易于维护

2.动态变化:如果需要在运行时根据需要动态地改变对象的行为,可以使用装饰器模式

3.统一接口:如果有一组具有相似功能但是又不完全相同的类,可以使用装饰器模式来统一它们的接口,使得在使用它们时不需要关心具体的类

4.延迟加载:如果某些数据是可选的,可以在需要时才加载,使用装饰器模式可以实现延迟加载的功能

5.处理复杂对象:当涉及到复杂的对象结构时,装饰器模式可以简化代码。通过将不同的行为封装到不同的装饰器中,可以组合这些装饰器来创建具有不同行为的对象

        装饰器模式适用于在不修改原有代码的基础上,动态地给对象添加新的行为。它适用于需要在运行时动态地改变对象行为或者需要统一接口的场景。

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

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

相关文章

Debezium-增量迁移之 Oracle 迁移所需权限

-- 创建用户 create user TCK identified by oracle; -- 赋权 grant connect,resource to TCK; -- 删除权限 revoke select any table from TCK; revoke select any DICTIONARY from TCK; -- 删除用户 CASCADE(用户下的数据级联删除) drop user TCK CASC…

拼多多订单打单接口 免申请审核流程接入(拼多多开放平台接入)

pdd.erp.order.sync erp打单信息同步 更新时间:2021-04-13 23:04:54 免费API必须用户授权 erp打单信息同步 公共参数 名称类型必须描述keyString是调用key(注册获取APIkey)secretString是调用密钥api_nameString是API接口名称&#xff…

JS中的扩展操作符...(点点点)

标题 前言概述拓展操作符(Spread Operator)赋值与扩展操作符的区别 剩余操作符(Rest Operator) 前言 大家应该都在代码中用过或者看到…方法,我每次用到这个方法的时候都会想到第一次见到这个方法一头雾水的样子&#…

淘宝/天猫 API 接入说明

API地址:https://o0b.cn/anzexi 调用示例: 参数说明 通用参数说明 参数不要乱传,否则不管成功失败都会扣费url说明 https://api-gw.onebound.cn/平台/API类型/ 平台:淘宝,京东等, API类型:[item_search,item_get,ite…

数学建模--粒子群算法(PSO)的Python实现

目录 1.开篇提示 2.算法流程简介 3.算法核心代码 4.算法效果展示 1.开篇提示 """ 开篇提示: 这篇文章是一篇学习文章,思路和参考来自:https://blog.csdn.net/weixin_42051846/article/details/128673427?utm_mediumdistribute.pc_relevant.none-task-blog-…

F#奇妙游(25):ADT和领域设计

前言 采用ADT来对领域进行设计,是一种很好的实践。在这种实践中,我们可以把领域中的数据抽象成ADT,把领域中的操作抽象成函数,然后利用ADT的类型系统来进行类型检查,从而保证领域中的数据和操作的正确性。 设计目标 …

【AGC】云数据库API9开发问题汇总

【问题描述】 云数据库HarmonyOS API9 SDK已经推出了一段时间了,下面为大家汇总一些在集成使用中遇到的问题和解决方案。 【问题分析】 1. 报错信息:数据库初始化失败:{“message”:“The object type list and permission …

云原生Kubernetes:K8S常用服务端口

目录 一、理论 1.K8S常用服务端口号 一、理论 1.K8S常用服务端口号 (1)K8S集群 表1 K8S集群端口 协议端口号K8S集群TCP22使用主机驱动通过SSH进行节点配置TCP2376主机驱动与Docker守护进程通信的TLS端口TCP2379etcd客户端请求TCP2380etcd节点通信U…

PgSQL-并行查询系列-介绍[译]

PgSQL-并行查询系列-介绍 现代CPU模型拥有大量的CPU核心。多年来,数据库应用程序都是并发向数据库发送查询的。查询处理多个表的行时,若可以使用多核,则可以客观地提升性能。PgSQL 9.6引入了并行查询的新特性,开启并行查询后可以大…

es(Elasticsearch)介绍

学习es可以参考mysql(相比mysql而言,es所需的cpu、内存更多) 什么是Elasticsearch Elasticsearch简称es,是由Elastic和search组成。Elastic的意思是有弹性的,search的意思是搜索。 弹性:es是一个天生支持分…

笔记:linux中LED(GPIO)驱动设备树配置和用法

设备树中节点配置 设备树中的LED驱动一般是这样写&#xff0c;LED驱动可以控制GPIO的电平变化&#xff0c;生成文件节点很方便 leds: leds {compatible "gpio-leds";gpio_demo: gpio_demo {label "gpio_demo";gpios <&gpio0 RK_PC0 GPIO_ACTIV…

晶圆键合对准机的原理与应用

一、晶圆键合设备的工作原理 1、 第一个晶圆面朝下置于晶圆对准设备卡盘并传送到对准机内&#xff1b; 2、对准机内&#xff0c;晶圆在Z轴方向上移动直到被顶部的传输夹具真空吸附固定&#xff1b; 3、被传输夹具固定的第一个晶圆将成为后续对准工艺的基准&#xff0c;确定所…

51、基于注解方式开发Spring WebFlux,实现生成背压数据,就是实现一直向客户端发送消息

★ Spring WebFlux的两种开发方式 1. 采用类似于Spring MVC的注解的方式来开发。此时开发时感觉Spring MVC差异不大&#xff0c;但底层依然是反应式API。2. 使用函数式编程来开发★ 基于注解开发Spring WebFlux 开发上变化并不大&#xff0c;主要是处理方法的返回值可使用Mon…

大数据组件系列-Hadoop每日小问

1、谈谈对HDFS的理解&#xff1f;HDFS这种存储适合哪些场景&#xff1f; HDFS即Hadoop Distributed File System&#xff0c;Hadoop 分布式文件系统。它为的是解决海量数据的存储与分析的问题&#xff0c;它本身是源于Google在大数据方面的论文&#xff0c;GFS-->HDFS; HD…

Mybatis的三种映射关系以及联表查询

目录 一、概念 二、一对一 1、配置generatorConfig.xml 2、Vo包的编写 3、xml的sql编写 4、编写对应接口及实现类 5、测试 三、一对多 1、Vo包类的编写 2、xml的sql编写 3、编写对应接口及实现类 4、测试 四、多对多 1、Vo类 2、xml的sql配置 3、接口及接口实现…

文件编辑器、用户管理,嘎嘎学

打开文件 vim # 首先你先得下载这个插件 yum install -y vim vim 文件名 进入编辑模式 i #在光标所在处进入编辑模式 a #在当前光标后面进入编辑模式 o #在光标的下一行进入编辑模式 I #在光标所在处行首进入编辑模式 A #在光标所在处行尾进入编辑模式 O #在光标的上一…

本地使用GFPGAN进行图像人脸修复

人脸修复 1.下载项目和权重文件2.部署环境3.下载权重文件4.运行代码5.网页端体验 首先来看一下效果图 1.下载项目和权重文件 https://github.com/iptop/GFPGAN-for-Video.git2.部署环境 根据README文件部署好环境&#xff0c;额外还需要&#xff1a; cd GFPGAN-1.3.8 pyt…

介绍GitHub

GitHub 是一个基于互联网的源代码托管平台&#xff0c;可以帮助软件开发者存储和管理源代码&#xff0c;方便团队协作和版本控制。GitHub 的主要功能包括&#xff1a; 代码托管&#xff1a;开发者可以在 GitHub 上创建远程代码仓库&#xff0c;存储和管理他们的源代码。 版本控…

金融信创,软件规划需关注自主安全及生态建设

软件信创化&#xff0c;就是信息技术软件应用创新发展的意思&#xff08;简称为“信创”&#xff09;。 相信在中国&#xff0c;企业对于“信创化”这个概念并不陌生。「国强则民强」&#xff0c;今年来中国经济的快速发展&#xff0c;受到了各大欧美强国的“卡脖子”操作的影…

大数据面试题:MapReduce压缩方式

面试题来源&#xff1a; 《大数据面试题 V4.0》 大数据面试题V3.0&#xff0c;523道题&#xff0c;679页&#xff0c;46w字 可回答&#xff1a;1&#xff09;Hadoop常见的压缩算法有哪些&#xff1f; 问过的一些公司&#xff1a;网易云音乐(2022.11)&#xff0c;阿里(2020.…