结构型设计模式(三)享元模式 代理模式 桥接模式

享元模式 Flyweight

1、什么是享元模式

享元模式的核心思想是共享对象,即通过尽可能多地共享相似对象来减少内存占用或计算开销。这意味着相同或相似的对象在内存中只存在一个共享实例。

2、为什么使用享元模式

  1. 减少内存使用:通过共享相似对象,减少了系统中对象的数量,从而减少了内存的使用。
  2. 提高性能:由于共享对象减少了创建和销毁的开销,提高了系统的性能。
  3. 简化代码:享元模式使得系统中的对象更加简单,因为需要相似的对象可以共享相同的状态。

3、如何使用享元模式

设计和实现一个文本编辑器,针对大量相似的字符对象,通过享元模式来共享相同字符对象

import java.util.HashMap;
import java.util.Map;// 抽象享元角色
interface CharFlyweight {void display();
}// 具体享元角色
class ConcreteCharFlyweight implements CharFlyweight {private char character;public ConcreteCharFlyweight(char character) {this.character = character;}@Overridepublic void display() {System.out.print(character);}
}// 享元工厂
class CharFlyweightFactory {private Map<Character, CharFlyweight> flyweights = new HashMap<>();public CharFlyweight getCharFlyweight(char character) {if (!flyweights.containsKey(character)) {flyweights.put(character, new ConcreteCharFlyweight(character));}return flyweights.get(character);}
}// 客户端代码
public class Client {public static void main(String[] args) {CharFlyweightFactory factory = new CharFlyweightFactory();CharFlyweight a = factory.getCharFlyweight('a');CharFlyweight b = factory.getCharFlyweight('b');CharFlyweight aAgain = factory.getCharFlyweight('a');a.display();  // 输出:ab.display();  // 输出:baAgain.display();  // 输出:a// 对比对象是否相同System.out.println("\nIs a the same object as aAgain? " + (a == aAgain));}
}

4、是否存在缺陷和不足

  1. 共享状态限制:享元模式主要适用于具有大量相似对象的情况,且这些对象可以共享状态。如果对象的状态不可共享,则不适合使用享元模式。
  2. 复杂性增加:在一些场景下,为了实现共享,需要将对象的一部分状态外部话,导致系统的复杂性增加。

5、如何缓解缺陷和不足

  1. 外部状态和内部状态分离:尽量将对象的外部状态(不可共享的状态)和内部状态(可共享的状态)清晰地分离,以便在不同的环境中使用。
  2. 合理使用享元模式:只有在系统中存在大量相似对象且能够共享状态时,才考虑使用享元模式,在其他情况下,可能并不切实际。

代理模式 Proxy

1、什么是代理模式

代理模式通过引入代理对象来控制对其他对象的访问。代理对象充当被代理对象的接口,可以在访问的时候添加额外的功能,比如安全性检查、缓存引入等操作功能。

2、为什么使用代理模式

  1. 控制访问:代理模式允许在访问对象时进行控制,可以添加额外的逻辑,比如权限检查、缓存引入等。
  2. 解耦:代理模式将客户端与目标对象解耦,客户端无需直接访问目标对象,降低了系统的耦合度。
  3. 延迟加载:代理模式可以实现延迟加载,在需要的时候再创建目标对象,提高系统的性能。

3、如何使用代理模式

设计实现一个 Image 接口,具体的实现类是 RealImage。通过代理模式,因为 ProxyImage 来控制对 RealImage 的访问

// 目标接口
interface Image {void display();
}// 具体目标类
class RealImage implements Image {private String filename;public RealImage(String filename) {this.filename = filename;loadFromDisk();}private void loadFromDisk() {System.out.println("Loading image: " + filename);}@Overridepublic void display() {System.out.println("Displaying image: " + filename);}
}// 代理类
class ProxyImage implements Image {private RealImage realImage;private String filename;public ProxyImage(String filename) {this.filename = filename;}@Overridepublic void display() {if (realImage == null) {realImage = new RealImage(filename);}realImage.display();}
}// 客户端代码
public class Client {public static void main(String[] args) {Image image = new ProxyImage("example.jpg");// 图像第一次加载image.display();// 图像第二次加载,使用缓存image.display();}
}

4、是否存在缺陷和不足

  1. 复杂性增加:引入代理对象可能会增加系统的复杂性,因为需要额外的类来管理代理和目标对象。
  2. 性能开销:在某些情况下,代理模式可能引入一定的性能开销,尤其是在代理对象的创建和销毁方面。

5、如何缓解缺陷和不足

  1. 智能代理:使用智能代理,根据具体情况选择是否创建目标对象,什么时候需要什么时候创建。
  2. 动态代理:使用动态代理,通过反射机制动态创建代理对象,减少手动创建代理对象的复杂性。

桥接模式 Bridge

1、什么是桥接模式

桥接模式的核心思想是将抽象部分和实现部分分离,使它们可以独立地发生变化。通过抽象类和实现类设计为两个独立的层次方案,并使用组合组合关系将他们连接起来。

2、为什么使用桥接模式

  1. 解耦抽象和实现:桥接模式将抽象和实现分离,使得他们可以独立地发生变化,降低系统的耦合度。
  2. 提高灵活性:桥接模式提高了系统的灵活性,可以更容易地添加新的抽象类和实现类。
  3. 复用性:可以在不修改已有代码的情况下引入新的抽象和实现。

3、如何使用桥接模式

设计实现一个图形绘制的场景,有不同类型的图形和不同的绘制方式,要求通过桥接模式将图形和绘制方式解耦。

// 实现部分 - 绘制方式
interface DrawingAPI {void drawCircle(int x, int y, int radius);
}// 具体实现部分 - 红色绘制方式
class RedDrawingAPI implements DrawingAPI {@Overridepublic void drawCircle(int x, int y, int radius) {System.out.println("Drawing Red Circle at (" + x + "," + y + ") with radius " + radius);}
}// 具体实现部分 - 绿色绘制方式
class GreenDrawingAPI implements DrawingAPI {@Overridepublic void drawCircle(int x, int y, int radius) {System.out.println("Drawing Green Circle at (" + x + "," + y + ") with radius " + radius);}
}// 抽象部分 - 图形
abstract class Shape {protected DrawingAPI drawingAPI;protected Shape(DrawingAPI drawingAPI) {this.drawingAPI = drawingAPI;}abstract void draw();
}// 具体抽象部分 - 圆形
class Circle extends Shape {private int x, y, radius;public Circle(int x, int y, int radius, DrawingAPI drawingAPI) {super(drawingAPI);this.x = x;this.y = y;this.radius = radius;}@Overridevoid draw() {drawingAPI.drawCircle(x, y, radius);}
}// 客户端代码
public class Client {public static void main(String[] args) {DrawingAPI redAPI = new RedDrawingAPI();DrawingAPI greenAPI = new GreenDrawingAPI();Shape redCircle = new Circle(100, 100, 10, redAPI);Shape greenCircle = new Circle(200, 200, 20, greenAPI);redCircle.draw();greenCircle.draw();}
}

4、是否存在缺陷和不足

  1. 增加复杂性:桥接模式可能会增加系统的复杂性,因为需要设计多个抽象类和实现的类层次结构。

5、如何缓解缺陷和不足

  1. 谨慎设计类的层次结构:设计抽象和实现的类层次结构时,需要谨慎考虑,避免过度设计。
  2. 使用合适的模式:根据系统的需求,考虑其他结构型模式,选择最适合的模式。

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

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

相关文章

汽车UDS诊断——SecureDataTransmission 加密数据传输(0x84)

诊断协议那些事儿 诊断协议那些事儿专栏系列文章,本文介绍诊断和通讯管理功能单元下的84服务SecureDataTransmission,在常规诊断通信中,数据极易被第三方获取,所以在一些特殊的数据传输时,标准定义了加密数据传输的服务。 简而言之,就是在发送诊断数据时,发送方先把数…

fragstats:景观指数的时间序列分析框架

作者&#xff1a;CSDN _养乐多_ 本文将介绍景观指数的时间序列分析计算的软件使用方法和 python 代码&#xff0c;该框架可用于分析景观指数时间序列图像的趋势分析、突变分析、机器学习&#xff08;分类/聚类/回归&#xff09;、相关性分析、周期分析等方面。 文章目录 一、…

智能优化算法应用:基于人工电场算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于人工电场算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于人工电场算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工电场算法4.实验参数设定5.算法结果6.…

04-Revision和流量管理

1 Revision 关于Revision 应用程序代码及相关容器配置某个版本的不可变快照KService上的spec.template的每次变动&#xff0c;都会自动生成一个新的Revision通常不需要手动创建及维护 Revision的使用场景 将流量切分至不同版本的应用程序间&#xff08;Canary Deployment、Blu…

静态路由及动态路由

文章目录 静态路由及动态路由一、静态路由基础1. 静态路由配置2. 负载分担3. 路由备份4. 缺省路由5. 静态路由实操 二、RIP 动态路由协议1. RIP 协议概述2. RIP 协议版本对比2.1 有类路由及无类路由 3. RIP 路由协议原理4. RIP 计时器5. 度量值6. 收敛7. 示例 静态路由及动态路…

Kafka基本原理及使用

目录 基本概念 单机版 环境准备 基本命令使用 集群版 消息模型 成员组成 1. Topic&#xff08;主题&#xff09;&#xff1a; 2. Partition&#xff08;分区&#xff09;&#xff1a; 3. Producer&#xff08;生产者&#xff09;&#xff1a; 4. Consumer&#xff08;…

使用TensorRT对Yolov5进行部署【基于Python】

如果还未配置TensorRT&#xff0c;请看这篇博文&#xff1a;Win11下TensorRT环境部署 这里使用TensorRT对Yolov5进行部署流程比较固定&#xff1a;先将pt模型转换为onnx&#xff0c;再将onnx模型转为engine&#xff0c;所以在执行export.py时要将onnx、engine给到include。 P…

Linear Regression线性回归(一元、多元)

目录 介绍&#xff1a; 一、一元线性回归 1.1数据处理 1.2建模 二、多元线性回归 2.1数据处理 2.2数据分为训练集和测试集 2.3建模 介绍&#xff1a; 线性回归是一种用于预测数值输出的统计分析方法。它通过建立自变量&#xff08;也称为特征变量&#xff09;和因变…

【Redis】五、Redis持久化、RDB和AOF

文章目录 Redis持久化一、RDB&#xff08;Redis DataBase&#xff09;触发机制如何恢复rdb文件 二、AOF&#xff08;Append Only File&#xff09;三、扩展 Redis持久化 面试和工作&#xff0c;持久化都是重点&#xff01; Redis 是内存数据库&#xff0c;如果不将内存中的数据…

微服务实战系列之ZooKeeper(实践篇)

前言 关于ZooKeeper&#xff0c;博主已完整的通过庖丁解牛式的“解法”&#xff0c;完成了概述。我想掌握了这些基础原理和概念后&#xff0c;工作的问题自然迎刃而解&#xff0c;甚至offer也可能手到擒来&#xff0c;真实一举两得&#xff0c;美极了。 为了更有直观的体验&a…

uniapp 预览图片

preImg(index){let urls []this.images.map((item,i) > {if(indexi){urls.unshift(item.file_path)}else{urls.push(item.file_path)}})uni.previewImage({urls})}

linux之Samba服务器

环境&#xff1a;虚拟机CENTOS 7和 测试机相通 一、Samba服务器_光盘共享&#xff08;匿名访问&#xff09; 1.在虚拟机CENTOS 7安装smb服务&#xff0c;并在防火墙上允许samba流量通过 2. 挂载光盘 3.修改smb.conf配置文件&#xff0c;实现光盘匿名共享 4. 启动smb服务 5.在…

JVM基础扫盲

什么是JVM JVM是Java设计者用于屏蔽多平台差异&#xff0c;基于操作系统之上的一个"小型虚拟机"&#xff0c;正是因为JVM的存在&#xff0c;使得Java应用程序运行时不需要关注底层操作系统的差异。使得Java程序编译只需编译一次&#xff0c;在任何操作系统都可以以相…

英码科技受邀参加2023计算产业生态大会,分享智慧轨道交通创新解决方案

12月13-14日&#xff0c;“凝心聚力&#xff0c;共赢计算新时代”——2023计算产业生态大会在北京香格里拉饭店成功举办。英码科技受邀参加行业数字化分论坛活动&#xff0c;市场总监李甘来先生现场发表了题为《AI哨兵&#xff0c;为铁路安全运营站好第一道岗》的精彩主题演讲&…

1951 年以来的美国ACIS 气候地图数据集(5 公里空间分辨率)

应用气候信息系统 (ACIS) NRCC NN ACIS是Applied Climate Information System的缩写&#xff0c;是由美国国家气象局&#xff08;NOAA&#xff09;开发的一种气候信息系统。ACIS气候地图是通过收集和整理全球的气象数据&#xff0c;利用计算机技术和数据分析方法生成的气候图表…

计算机组成原理-选择语句和循环语句的汇编表示

文章目录 选择语句jmpjxx示例&#xff1a;选择语句的机器级表示扩展&#xff1a;cmp指令的底层原理 循环语句使用条件转移指令实现循环用loop指令实现循环 选择语句 不一定知道指令的位置&#xff0c;所以jmp直接跳转到指令的位置很难办 jmp 标号相当于位置&#xff0c;名字…

解决win11杀毒(不能安装破解软件的问题)

1、下载火绒APP&#xff0c;打开火绒APP软件 2、点击菜单&#xff0c;选择安全设置 3、选择病毒防护&#xff0c;修改病毒处理方式为询问我 4、这样在解压激活的软件就不会被windows的杀毒软件自动删除了 5、问题解决了就点击三连吧

永久删除的文件如何恢复?这3个简单方法可以帮到你!

“我在清理电脑的过程中&#xff0c;一不小心就删除了一些很重要的文件和数据&#xff0c;很想通过某种方法将这些数据找回来&#xff0c;但是不知道应该如何操作&#xff0c;有朋友可以分享一下文件找回的简单方法吗&#xff1f;” 在日常生活和工作中&#xff0c;我们时常会遇…

【JAVA基础(对象和封装以及构造方法)】----第四天

对象和封装以及构造方法 面向对象和面向过程面向过程面向对象 类与对象及其使用定义类创建一个对象&#xff0c;操作类补充&#xff08;成员变量和局部变量&#xff09; private 修饰类 封装练习编写类编写测试输出结果 面向对象和面向过程 面向过程 在了解面向对象之前先来了…

用户行为分析遇到的问题-ubantu16,hadoop3.1.3【更新中】

用户行为分析传送门 我的版本 ubantu16 hadoop 3.1.3 habse 2.2.2 hive3.1.3 zookeeper3.8.3 sqoop 1.46/1.47 我sqoop把MySQL数据往hbase导数据时候有问题 重磅&#xff1a;大数据课程实验案例&#xff1a;网站用户行为分析&#xff08;免费共享&#xff09; 用户行为分析-小…