【重温设计模式】装饰模式及其Java示例

news2024/11/15 5:00:02

装饰模式的介绍

在众多设计模式中,有一种叫做装饰模式,它以一种独特的方式赋予了代码更多的灵活性。

装饰模式是一种结构型设计模式,它允许我们在运行时动态地为对象添加新的行为。这就像是我们在装饰一个房间时,可以随意添加或更换装饰品,而不需要对整个房间进行改造。装饰模式的特点是,它可以保持代码的清晰和简洁,同时提供了强大的扩展性。这种模式在很多场景中都有应用,比如在Java的IO流中,我们就可以看到装饰模式的影子。

public class OneMore {
    public void doSomething() {
        System.out.println("Do something in OneMore class");
    }
}

public class Decorator extends OneMore {

    @Override
    public void doSomething() {
        super.doSomething();
        oneMore.doSomething();
    }
}

在上面的Java代码示例中,我们定义了一个基类OneMore和一个装饰器类Decorator。装饰器类Decorator继承了OneMore类,并重写了doSomething方法,在方法中调用了OneMore类的doSomething方法。这样,我们就可以动态地为OneMore类添加新的行为,而不需要修改OneMore类的代码。

这只是装饰模式的一种简单应用,接下来我们将深入探讨装饰模式背后的设计原则。

装饰模式的设计原则

在理解了装饰模式的基本概念后,我们来深入探讨装饰模式背后的设计原则。装饰模式是一种结构型设计模式,其主要目标是通过动态添加或覆盖方法,来扩展一个对象的功能。这种模式的设计理念,恰恰体现了两个重要的设计原则:开闭原则和单一职责原则。

首先,装饰模式实现了开闭原则。这个原则的核心思想是“对扩展开放,对修改关闭”。在装饰模式中,如果我们需要增加新的功能,只需要添加一个新的装饰类即可,无需修改原有的代码。这就避免了因修改代码而引发的可能的错误或者对原有功能的影响。例如,假设我们有一个Java类OneMore,现在我们想给它添加一个新的功能,我们可以创建一个装饰类,如下:

public class Decorator extends OneMore {
    @Override
    public void function() {
        super.function();
        addedFunction();
    }

    public void addedFunction() {
        // New function
    }
}

这样,我们就在不修改OneMore类的情况下,给它添加了新的功能。

其次,装饰模式实现了单一职责原则。这个原则要求一个类应该只有一个引起它变化的原因。在装饰模式中,每个装饰类都只负责一个功能的添加,这样就避免了一个类承担过多的责任,使得代码更加清晰和可维护。

通过以上的讨论,我们可以看出装饰模式的设计理念是非常符合软件开发中的设计原则的。接下来,我们将通过一个具体的Java实例,来展示如何在Java中实现装饰模式。

Java中的装饰模式实例

在理解了装饰模式的设计原则后,让我们通过一个具体的Java程序示例来展示如何在Java中实现装饰模式。这里我们将设计一个简单的“书籍”类,这个类有一个“阅读”方法。然后,我们将创建一个名为“OneMore”的装饰类,它将增强“书籍”类的“阅读”方法,使其在阅读书籍的同时,还能进行一些其他的功能,如记笔记。

首先,让我们定义一个简单的“书籍”类:

public class Book {
    public void read() {
        System.out.println("Reading a book...");
    }
}

然后,我们创建一个名为“OneMoreBook”的装饰类,它也有一个“阅读”方法。在这个方法中,我们首先调用了原始的“阅读”方法,然后增加了一些新的功能:

public class OneMoreBook extends Book {
    public void read() {
        super.read();
        System.out.println("And taking notes...");
    }
}

在上述代码中,我们首先创建了一个新的“OneMoreBook”类,它继承了“Book ”类,并在其内部定义了一个“read”方法。在“OneMoreBook”类的“read”方法中,首先调用了原始“Book ”类的“阅读”方法,然后增加了一些新的功能。

这就是一个简单的装饰模式的实例,通过这个实例,我们可以看到,装饰模式可以在不改变原始类的基础上,动态地扩展其功能。当然,这只是装饰模式的一种应用,它的优缺点及适用场景还有很多,接下来我们将进一步探讨这个话题。

装饰模式的优缺点及适用场景

在上面的例子中,我们可以看到装饰模式的一大优点:它提供了一种非常灵活的方式来扩展对象的功能,而不需要修改原有对象的代码。这是因为装饰模式是在运行时动态地将新功能添加到对象上,而不是在编译时。这使得我们可以在不影响其他对象的情况下,为特定的对象添加新的功能。

然而,装饰模式并不是万能的。它的一个主要缺点是会导致设计中出现大量的小对象。如果过度使用装饰模式,可能会使程序变得复杂,难以理解和维护。

至于装饰模式的适用场景,通常来说,当我们需要给一个对象动态添加功能,或者给一组对象添加相同的功能时,装饰模式都是一个不错的选择。例如,在Java的IO流中,就广泛使用了装饰模式,使得我们可以灵活地为一个流添加各种各样的处理功能,如缓冲、压缩和字符编码转换等。

总的来说,装饰模式是一种非常有用的设计模式,它能够提供一种简洁、灵活的方式来扩展对象的功能。但是,正如我们所讨论的,它也有其缺点和限制。因此,在实际开发中,我们需要根据具体的需求和场景,灵活地选择和使用装饰模式。

总结

装饰模式,这个看似简单却又深奥的设计模式,希望在我的介绍下,你能有所理解和掌握。这种模式,就像一个装饰师,给我们的代码添加了更多的灵活性和可扩展性,让我们的代码更加美观和实用。

但是,正如我所说的,装饰模式并不是万能的,它也有其局限性,可能会导致程序设计中出现大量的小对象,增加了程序的复杂性。因此,我们在使用时,需要根据具体的需求和场景,灵活地选择和使用装饰模式。

在编程的世界里,没有最好的设计模式,只有最适合的设计模式。每一种设计模式都有其独特的优点和适用场景,我们需要做的,就是去理解它,掌握它,然后在合适的地方,合适的时机,使用它。

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

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

相关文章

学习网络编程No.11【传输层协议之UDP】

引言: 北京时间:2023/11/20/9:17,昨天成功更文,上周实现了更文两篇,所以这周再接再厉。当然做题任在继续,而目前做题给我的感觉以套路和技巧偏多,还是那句话很多东西不经历你就是不懂&#xff…

C#入门:简单数据类型和强制类型转换

本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com 本期来讲讲 unity 的脚本语言 —C#,C# 的简单数据类型及范围和强制类型转化的方法。这可是 unity 游戏开发必备技能。 1. 简单数据类型 各个类型的范围: byte -> System.Byte (字节…

roslaunch 报错 numpy与python版本冲突

报错&#xff1a; File "/usr/lib/python3/dist-packages/numpy/core/__init__.py", line 17, in <module> from . import multiarray File "/usr/lib/python3/dist-packages/numpy/core/multiarray.py", line 14, in <module> from . import…

蓝桥杯练习系统(算法训练)ALGO-992 士兵杀敌(二)

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 南将军手下有N个士兵&#xff0c;分别编号1到N&#xff0c;这些士兵的杀敌数都是已知的。   小工是南将军手下的军师&…

gif闪图如何在线生成?仅需三步在线制作gif闪图

Gif动态图片是一种通过连续播放的一系列图片来展示的。Gif动图的优势是体积小、传播速度快且不受限制。当我们想要将多张图片变成带有闪动效果的gif动图时应该怎么操作呢&#xff1f;这时候&#xff0c;只需要使用在线闪图制作&#xff08;https://www.gif.cn/&#xff09;网站…

【C++初阶】内存管理

目录 一.C语言中的动态内存管理方式 二.C中的内存管理方式 1.new/delete操作内置类型 2.new和delete操作自定义类型 3.浅识抛异常 &#xff08;内存申请失败&#xff09; 4.new和delete操作自定义类型 三.new和delete的实现原理 1.内置类型 2.自定义类型 一.C语…

全部免费!抖音,牛逼了!

相比于百度文心、清华智谱和讯飞星火这些在国内有一定市场知名度的AI工具&#xff0c;字节跳动多少显得有点低调了。 国内的AI工具用了不少&#xff0c;但要是说哪家最有前景&#xff0c;那最看好的还是字节跳动。 倒不是说字节的云雀大模型比上面这几个更牛逼&#xff0c;而…

uniapp_微信小程序_说下动态class(实用性很强)

// 以上图片为例,里面的参数是后端传给你的&#xff0c;你不知道有多少东西&#xff0c;更不可能一个一个改&#xff0c;所以引入动态class 代码实现 <view :class"{ pay: item.paymoneystatus 未支付,inpay: item.paymoneystatus 已支付}">{{item.paymon…

Python之Flask框架~四大内置对象

1.g global全局对象 g对象是专门用来保存用户的数据的 g对象在一次请求中的所有的代码的地方, 都是可以使用的 突破变量存储位置限制,为数据传递添加了新的方式,比如我们在before_request产生一个数据在后面需要使 用, 可以保存在g对象中, 在其他视图西数中就可以使用这个数据…

YOLOv6、YOLOv7、YOLOv8网络结构图(清晰版)

承接上一篇博客&#xff1a;YOLOv3、YOLOv4、YOLOv5、YOLOx的网络结构图(清晰版)_yolox网络结构图-CSDN博客 1. YOLOv6网络结构图 2. YOLOv7网络结构图 3. YOLOv8网络结构图

中文地址命名实体识别预测写入csv格式

模型训练参数 中文地址命名实体识别训练和预测 效果 输入数据 输出数据 脚本 import os import numpy as np import torch import json from utils import commonUtils, metricsUtils, decodeUtils, trainUtils import b

《Linux C编程实战》笔记:共享内存

共享内存是分配一块能被其他进程访问的内存。每个共享内存段在内核中维护一个内部数据结构shmid_ds(和消息队列、信号量一样)&#xff0c;该结构定义在头文件linux/shm.h中,这是我从源码里抄的 #include<linux/shm.h> struct shmid_ds {struct ipc_perm shm_perm; /* 操…

pytorch基础2-数据集与归一化

专题链接&#xff1a;https://blog.csdn.net/qq_33345365/category_12591348.html 本教程翻译自微软教程&#xff1a;https://learn.microsoft.com/en-us/training/paths/pytorch-fundamentals/ 初次编辑&#xff1a;2024/3/2&#xff1b;最后编辑&#xff1a;2024/3/2 本教程…

swagger在java中的基本使用

自动生成接口文档&#xff0c;和在线接口测试的框架。 导入依赖 <!-- knife4j对swagger进行一个封装--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><versi…

StarCoder2本地部署上手体验:程序猿要下岗了吗?

StarCoder2简介 ServiceNow、Hugging Face 和 NVIDIA 于2月28日宣布发布 StarCoder2&#xff0c;这是一个用于代码生成的开放式大型语言模型系列&#xff0c;为性能、透明度和成本效益设定了新标准。StarCoder2 是与 BigCode 社区合作开发的&#xff0c;由ServiceNow和 Huggin…

labview数组精讲

题主经过写文章一段时间的发现,许多同学对该软件的理解和编程能力是不太一样的,有些知识相对一些同学较为简单,但是有些同学提问就比较困难。那么针对这个问题,题主打算出一期说白话系列的专栏,在该栏目中用最通俗的大白话和例子去让大家深刻了解这个软件的功能和摸透他的…

Py2neo查询neo4j周杰伦数据库中的节点、关系和路径教程

文章目录 py2neo介绍连接Neo4j数据库py2neo查询图数据库neo4j数据概览使用NodeMatcher查询节点使用RelationshipMatcher查询关系 通过执行Cypher语句查询 py2neo介绍 Neo4j是一款开源图数据库&#xff0c;Py2neo提供了使用Python语言访问Neo4j的接口。本文介绍了使用Py2neo的N…

钉钉机器人发送折线图卡片 工具类代码

钉钉机器人 “创建并投放卡片 接口 ” 可以 发送折线图、柱状图 官方文档&#xff1a;创建并投放卡片 - 钉钉开放平台 0依赖、1模板、2机器人放到内部应用、3放开这个权限 、4工具类、5调用工具类 拼接入参 卡片模板 自己看文档创建&#xff0c;卡片模板的id 有用 0、依赖…

vue2 设置keepAlive之后怎么刷新页面数据

场景&#xff1a;移动端有 A、B、C 三个页面&#xff0c;A、B 页面路由设置了keepAlive属性&#xff0c;有下面两个场景&#xff1a; 1、A 页面 --> B 页面&#xff0c;B 页面刷新。 2、C 页面 --> B页面&#xff0c;B 页面不刷新。 一、分为以下两个情况讨论&#xf…

Linux安装Nginx配置Keepalived高可用

Vmwaire 安装 Linux 解决启动没有IP地址问题 cd /etc/sysconfig/network-scripts vi ifcfg-ens33# 重启linux reboot # 再次查看ip ip addrLinux 镜像地址下载 ps: 发现阿里有一个工具箱&#xff0c;里面有各种镜像 阿里镜像地址 https://developer.aliyun.com/mirror/ 安装…