【设计模式】结构型模式(一):适配器模式、装饰器模式

结构型模式(一):适配器模式、装饰器模式

  • 1.适配器模式(Adapter)
  • 2.装饰器模式(Decorator)
    • 2.1 主要特点
    • 2.2 组成部分
    • 2.3 示例代码
      • 2.3.1 Component 组件
      • 2.3.2 ConcreteComponent 具体组件
      • 2.3.3 Decorator 装饰器
      • 2.3.4 ConcreteDecorator 具体装饰器
      • 2.3.5 客户端代码
    • 2.4 总结

1.适配器模式(Adapter)

适配器模式Adapter Pattern)是一种结构型设计模式,其主要目的是通过适配器将一个接口转换为客户端所期望的另一个接口。这个模式允许你为现有类增加新功能,或者让它们之间兼容,而无需修改其源代码。适配器模式可以分为两类:

  • 类适配器模式:通过继承来适配一个类的接口。
  • 对象适配器模式:通过组合来适配一个类的接口。

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

  • 目标接口Target):这是客户端所期望的接口,可以是一个类或一个接口。
  • 适配者Adaptee):这是需要适配的接口,即拥有不兼容接口的对象。
  • 适配器Adapter):这是关键部分,它 持有适配者对象的实例,并且可以 调用适配者的方法,同时 实现目标接口,从而使得适配者接口和目标接口兼容。

在这里插入图片描述

假设有一个类 AmericanPlug,其接口与我们的需求不兼容。我们希望使用这个类,但需要将其适配到我们所需的接口 ChinesePlug

// 目标接口
interface ChinesePlug {
    void connect();
}

// 适配者
class AmericanPlug {
    public void plugIn() {
        System.out.println("American Plug is connected.");
    }
}

// 适配器
class Adapter extends AmericanPlug implements ChinesePlug {
    @Override
    public void connect() {
        super.plugIn();
    }
}

public class AdapterPatternExample {
    public static void main(String[] args) {
        ChinesePlug plug = new Adapter();
        plug.connect(); // 输出 "American Plug is connected."
    }
}

在这个例子中,Adapter 类继承了 AmericanPlug 类并实现了 ChinesePlug 接口。通过这个适配器,客户端可以使用 ChinesePlug 接口,而实际上调用的是 AmericanPlug 类的方法。

适配器模式可以使得你复用现有的类,而不必修改它们的接口,同时增加了系统的灵活性和可扩展性。

2.装饰器模式(Decorator)

装饰器模式Decorator Pattern)是一种结构型设计模式,允许在运行时动态地为对象添加行为和职责,而不需要修改对象的结构。通过这种方式,可以 在不使用子类的情况下扩展对象的功能,提供了一种灵活的替代继承的方案。

2.1 主要特点

  • 动态扩展:可以在运行时动态地为对象添加功能,而不需要修改原有的类。
  • 透明性:装饰器类和被装饰的类具有相同的接口,客户端代码可以在不改变代码的情况下使用装饰后的对象。
  • 组合优于继承:避免了大量子类的产生,使代码更加灵活和可维护。

2.2 组成部分

  • Component组件):
    • 定义一个接口或抽象类,表示 被装饰的对象
    • 具体组件实现这个接口或抽象类。
  • ConcreteComponent具体组件):
    • 实现 Component 接口,提供基本的行为或功能。
  • Decorator装饰器):
    • 持有一个 Component 对象的引用。
    • 实现 Component 接口,可以在调用具体组件的方法前后添加新的行为。
  • ConcreteDecorator具体装饰器):
    • 继承自 Decorator,实现具体的装饰行为。

2.3 示例代码

以下是一个简单的 Java 示例,展示了如何使用装饰器模式为文本添加不同的格式。

2.3.1 Component 组件

// Component 组件
interface TextComponent {
    String getText();
}
  • TextComponent:定义了一个接口,声明了一个 getText 方法。这个接口表示 被装饰的对象 的基本行为。

2.3.2 ConcreteComponent 具体组件

// ConcreteComponent 具体组件
class SimpleText implements TextComponent {
    private String text;

    public SimpleText(String text) {
        this.text = text;
    }

    @Override
    public String getText() {
        return text;
    }
}
  • SimpleText:实现了 TextComponent 接口,提供了一个具体的文本实现。
    • 属性text,存储具体的文本内容。
    • 构造方法SimpleText(String text),初始化文本内容。
    • 方法getText(),返回存储的文本内容。

2.3.3 Decorator 装饰器

// Decorator 装饰器
abstract class TextDecorator implements TextComponent {
    protected TextComponent component;

    public TextDecorator(TextComponent component) {
        this.component = component;
    }

    @Override
    public String getText() {
        return component.getText();
    }
}
  • TextDecorator:抽象类,持有一个 TextComponent 对象的引用,实现了 TextComponent 接口。
    • 属性component,存储被装饰的组件。
    • 构造方法TextDecorator(TextComponent component),初始化 被装饰的组件
    • 方法getText(),调用被装饰组件的 getText 方法,返回其文本内容。这个方法在具体装饰器中可以被重写,以添加额外的行为

2.3.4 ConcreteDecorator 具体装饰器

// ConcreteDecorator 具体装饰器
class BoldTextDecorator extends TextDecorator {
    public BoldTextDecorator(TextComponent component) {
        super(component);
    }

    @Override
    public String getText() {
        return "<b>" + super.getText() + "</b>";
    }
}

class ItalicTextDecorator extends TextDecorator {
    public ItalicTextDecorator(TextComponent component) {
        super(component);
    }

    @Override
    public String getText() {
        return "<i>" + super.getText() + "</i>";
    }
}
  • BoldTextDecorator具体的装饰器,继承自 TextDecorator,为文本添加粗体格式。
    • 方法getText(),在被装饰组件的文本内容前后添加 <b></b> 标签。
  • ItalicTextDecorator具体的装饰器,继承自 TextDecorator,为文本添加斜体格式。
    • 方法getText(),在被装饰组件的文本内容前后添加 <i></i> 标签。

2.3.5 客户端代码

// 客户端代码
public class DecoratorPatternExample {
    public static void main(String[] args) {
        // 创建一个简单的文本组件
        TextComponent simpleText = new SimpleText("Hello, World!");
        
        // 为简单文本添加粗体装饰
        TextComponent boldText = new BoldTextDecorator(simpleText);
        // 为粗体文本添加斜体装饰
        TextComponent italicBoldText = new ItalicTextDecorator(boldText);

        System.out.println(simpleText.getText()); // 输出原始文本: Hello, World!
        System.out.println(boldText.getText());   // 输出粗体文本: <b>Hello, World!</b>

        System.out.println(italicBoldText.getText()); // 输出斜体和粗体文本: <i><b>Hello, World!</b></i>

    }
}

2.4 总结

通过装饰器模式,可以在不修改原有类的情况下,动态地为对象添加新的功能。这种方式使得代码更加灵活和可扩展,避免了大量子类的产生。

  • 优点
    • 灵活性:可以在运行时动态地添加或删除功能。
    • 可扩展性:通过组合不同的装饰器,可以轻松地创建复杂的对象。
    • 代码复用:避免了大量子类的产生,减少了代码的复杂性。
  • 缺点
    • 复杂性:过多的装饰器可能会使代码变得复杂,难以维护。
    • 性能:每次调用方法时都需要额外的处理,可能会有性能开销。

装饰器模式在许多框架和库中都有应用,例如 Java I/O 流中的 BufferedInputStreamDataInputStream,以及 Spring 框架中的 AOP(面向切面编程)。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

交换机的基本配置

交换机的基本配置 实验题目实验目的实验任务实验设备实验环境实验步骤VLAN 的简单配置跨交换机 vlan 的配置主机配置信息表解释&#xff1a; vlan 间路由 实验题目 交换机的基本配置。 实验目的 1) 理解交换机的原理和应用场景&#xff1b; 2) 交换机的基本指令系统&#xf…

QFrameWork学习指南

QFramework官网地址&#xff1a;Wiki - 木兰确实 1、界面设计 &#xff08;1&#xff09;CounterAppController的界面 BtnAdd和BtnSub为Button组件&#xff0c;CountText为Text组件&#xff0c;后续的脚本挂载Canvas上。 &#xff08;2&#xff09;OnGUI OnGUI是Unity中通过…

黄金价格下跌,原油价格激增,小麦价格面临阻力

黄金价格回落 现货黄金价格达到每金衡盎司 $2,790.00 的新纪录高点&#xff0c;接近心理关口 $2,800.00&#xff0c;随后在部分交易员在周五美国非农就业数据&#xff08;NFPs&#xff09;公布前以及下周美国选举前套现利润的回撤中下跌至 $2,732.00。 在 $2,732.00 以下是 10…

DiskGenius一键修复磁盘损坏

下午外接磁盘和U盘都出现扇区损坏&#xff0c;估计就是在开着电脑&#xff0c;可能是电脑运行的软件还在对磁盘进行读写&#xff0c;不小心按到笔记本关机键&#xff0c;重新开机读写磁盘分区变得异常卡顿&#xff0c;估摸就是这个原因导致扇区损坏。在进行读写时&#xff0c;整…

智慧国土空间规划方法探索与实践应用

在数字化时代背景下&#xff0c;国土空间规划正经历着一场深刻的变革。智慧国土空间规划作为一种新兴的规划理念和方法&#xff0c;其核心在于利用现代信息技术&#xff0c;提高规划的科学性、精准性和动态适应性。本文将探讨智慧国土空间规划的方法探索与实践应用。 1. 智慧国…

从零开发操作系统-为什么磁盘的扇区为 512 byte

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

一文了解Android SELinux

在Android系统中&#xff0c;SELinux&#xff08;Security-Enhanced Linux&#xff09;是一个增强的安全机制&#xff0c;用于对系统进行强制访问控制&#xff08;Mandatory Access Control&#xff0c;MAC&#xff09;。它限制了应用程序和进程的访问权限&#xff0c;提供了更…

Redis-持久化(增量模式和全量模式)

文章目录 一、持久化和Redis持久化概念持久化介绍Redis持久化的介绍全量模式持久化技术——RDB增量模式持久化技术——AOF使用RDB还是AOF? 二、RDB配置以及数据恢复的简单实现RDB快照的工作方式如何关闭RDB持久化功能如何模拟Redis服务器数据丢失&#xff1f;然后再如何具体使…

SQL 常用语句

目录 我的测试环境 学习文档 进入数据库 基础通关测验 语句-- 查 展示数据库&#xff1b; 进入某个数据库&#xff1b; 展示表&#xff1a; 展示某个表 desc 查询整个表&#xff1a; 查询特定列&#xff1a; 范围查询 等于特定值 不等于 介于 特定字符查询 Li…

MFC图形函数学习05——画椭圆函数

MFC中有一个专门绘制椭圆的函数&#xff0c;其参数与绘制矩形参数相同&#xff0c;实际上所绘制的椭圆就是矩形的内切圆椭圆。 一、绘制椭圆函数 原型&#xff1a;BOOL Ellipse (int x1,int y1,int x2,int y2); 参数&#xff1a;椭圆内切矩形的左上角&#xff08…

Spring3(代理模式 Spring1案例补充 Aop 面试题)

Spring3 代理模式概述介绍什么是代理模式&#xff1f;为什么要使用代理模式&#xff1f;有哪几种代理模式&#xff1f;静态代理基于接口实现的动态代理(JDK自带)基于子类的动态代理 Spring_AOP_01案例补充(添加事务管理)实现完整代码&#xff1a;常规实现&#xff1a;代理实现 …

开源模型应用落地-Qwen2.5-7B-Instruct与TGI实现推理加速

一、前言 目前&#xff0c;大语言模型已升级至Qwen2.5版本。无论是语言模型还是多模态模型&#xff0c;均在大规模多语言和多模态数据上进行预训练&#xff0c;并通过高质量数据进行后期微调以贴近人类偏好。在本篇学习中&#xff0c;将集成 Hugging Face的TGI框架实现模型推理…

Android 使用ninja加速编译的方法

ninja的简介 随着Android版本的更迭&#xff0c;makefile体系逐渐增多&#xff0c;导致make单编模块的时间越来越长&#xff0c;每次都需要半个小时甚至更长时间&#xff0c;其原因为每次make都会重新加载所有mk文件&#xff0c;再生成ninja编译&#xff0c;此完整过程十分耗时…

javaNIO核心知识.中

Channel&#xff08;通道&#xff09; Channel 是一个通道&#xff0c;它建立了与数据源&#xff08;如文件、网络套接字等&#xff09;之间的连接。我们可以利用它来读取和写入数据&#xff0c;就像打开了一条自来水管&#xff0c;让数据在 Channel 中自由流动。 BIO 中的流…

缓存、注解、分页

一.缓存 作用&#xff1a;应用查询上&#xff0c;内存中的块区域。 缓存查询结果&#xff0c;减少与数据库的交互&#xff0c;从而提高运行效率。 1.SqlSession 缓存 1. 又称为一级缓存&#xff0c;mybatis自动开启。 2. 作用范围&#xff1a;同一…

流畅!HTMLCSS打造网格方块加载动画

效果演示 这个动画的效果是五个方块在网格中上下移动&#xff0c;模拟了一个连续的加载过程。每个方块的动画都是独立的&#xff0c;但是它们的时间间隔和路径被设计为相互协调&#xff0c;以创建出流畅的动画效果。 HTML <div class"loadingspinner"><…

【skywalking 】More than 15,000 ‘grammar‘ tokens have been presented. 【未解决请求答案】

问题 skywalking相关版本信息 jdk&#xff1a;17skywalking&#xff1a;10.1.0apache-skywalking-java-agent&#xff1a;9.3.0ElasticSearch : 8.8.2 问题描述 More than 15,000 grammar tokens have been presented. To prevent Denial Of Service attacks, parsing has b…

docker desktop使用ubuntu18.04带图形化+运行qemu

记录一下docker desktop使用ubuntu18.04带图形化命令和使用步骤 1. 下载镜像 参考&#xff1a;【Docker教程】Docker部署Ubuntu18.04(带图形化界面) 命令&#xff1a; docker pull kasmweb/ubuntu-bionic-desktop:1.10.02. 启动镜像 命令&#xff1a; docker run -d -it …

jmeter压测工具环境搭建(Linux、Mac)

目录 java环境安装 1、anaconda安装java环境&#xff08;推荐&#xff09; 2、直接在本地环境安装java环境 yum方式安装jdk 二进制方式安装jdk jmeter环境安装 1、jmeter单机安装 启动jmeter 配置环境变量 jmeter配置中文 2、jmeter集群搭建 多台机器部署jmeter集群…

ai翻唱部分步骤

模型部署 我是用的RVC进行的训练&#xff0c;也可以使用so-vits-svc。 通过百度网盘分享的文件&#xff1a;RVC-beta 链接&#xff1a;https://pan.baidu.com/s/1c99jR2fLChoqUFqf9gLUzg 提取码&#xff1a;4090 以Nvida显卡为例&#xff0c;分别下载“RVC1006Nvidia”和…