设计模式之桥接模式、组合模式与享元模式

目录

桥接模式

简介

优缺点

结构

实现

运用场景

组合模式

简介

优缺点

结构

实现

运用场景

享元模式

简介

优缺点

结构

实现

运用场景


桥接模式

简介

将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度

优缺点

优点:

        1.抽象与现实分离,扩展能力强

        2.符合开闭原则、合成复用原则

        3.实现细节透明

缺点:

        由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,能正确地识别出系统中两个独立变化的维度,这增加了系统的理解与设计难度

结构

可以将抽象化部分与实现化部分分开,取消二者的继承关系,改用组合关系

角色:

        抽象化角色:定义抽象类,并包含一个对实现化对象的应用

        扩展抽象化角色:抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法

        实现化角色:定义实现化角色的接口,供扩展抽象化角色调用

        具体实现化角色:给出实现化角色接口的具体实现

实现

package bridge;
public class BridgeTest {public static void main(String[] args) {Implementor imple = new ConcreteImplementorA();Abstraction abs = new RefinedAbstraction(imple);abs.Operation();}
}
//实现化角色
interface Implementor {public void OperationImpl();
}
//具体实现化角色
class ConcreteImplementorA implements Implementor {public void OperationImpl() {System.out.println("具体实现化(Concrete Implementor)角色被访问");}
}
//抽象化角色
abstract class Abstraction {protected Implementor imple;protected Abstraction(Implementor imple) {this.imple = imple;}public abstract void Operation();
}
//扩展抽象化角色
class RefinedAbstraction extends Abstraction {protected RefinedAbstraction(Implementor imple) {super(imple);}public void Operation() {System.out.println("扩展抽象化(Refined Abstraction)角色被访问");imple.OperationImpl();}
}
​

运用场景

        当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。

        当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。

        当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时

组合模式

简介

运用了树形结构,该模式的核心思想是:将多个对象组合成树形结构,以此结构来表示“整体-部分”之间的层次关系

优缺点

优点:

        1.使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码

        2.更容易在组合体内加入新的对象

缺点:

        设计较复杂,客户端需要花更多时间理清类之间的层次关系;

        不容易限制容器中的构件;

        不容易用继承的方法来增加构件的新功能

结构

角色:

        抽象构件角色:它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为

        树叶构件角色:是组合中的叶节点对象,它没有子节点,用于继承或实现抽象构件

        树枝构件角色 / 中间构件:是组合中的分支节点对象,它有子节点,用于继承和实现抽象构件

实现

public class CompositePattern {public static void main(String[] args) {Component c0 = new Composite();Component c1 = new Composite();Component leaf1 = new Leaf("1");Component leaf2 = new Leaf("2");Component leaf3 = new Leaf("3");c0.add(leaf1);c0.add(c1);c1.add(leaf2);c1.add(leaf3);c0.operation();}
}
//抽象构件
interface Component {public void add(Component c);public void remove(Component c);public Component getChild(int i);public void operation();
}
//树叶构件
class Leaf implements Component {private String name;public Leaf(String name) {this.name = name;}public void add(Component c) {}public void remove(Component c) {}public Component getChild(int i) {return null;}public void operation() {System.out.println("树叶" + name + ":被访问!");}
}
//树枝构件
class Composite implements Component {private ArrayList<Component> children = new ArrayList<Component>();public void add(Component c) {children.add(c);}public void remove(Component c) {children.remove(c);}public Component getChild(int i) {return children.get(i);}public void operation() {for (Object obj : children) {((Component) obj).operation();}}
}

运用场景

        在需要表示一个对象整体与部分的层次结构的场合

        要求对用户隐藏组合对象与单个对象的不同,用户可以用统一的接口使用组合结构中的所有对象的场合

享元模式

简介

        用于减少创建对象的数量,以减少内存占用和提高性能。它提供了减少对象数量从而改善应用所需的对象结构的方式;尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

优缺点

优点:

        减少内存使用:由于享元模式共享对象,因此可以减少内存使用。

        提高性能:创建和销毁对象会占用大量的CPU时间和内存空间。因此,使用享元模式可以提高性能。

        代码简洁:享元模式可以使代码更简洁,因为该模式使用相同的对象来处理多个请求,而不需要创建大量的对象。

缺点:

        共享对象可能会对线程安全造成问题。如果不正确地实现共享机制,则可能导致多个线程对同一对象进行更改,从而导致竞争条件。

        需要牺牲一定的时间和空间,来实现对象共享和控制机制。这意味着,当对象之间没有重复性时,使用享元模式可能会导致额外的开销

结构

角色:

        抽象享元角色:通常是一个接口或抽象类,在抽象享元类中声明了具体享元类公 共的方法,这些方法可以向外界提供享元对象的内部数据(内部状态),同时也可以通过这些方法 来设置外部数据(外部状态)。

        具体享元角色 :它实现了抽象享元类,称为享元对象;在具体享元 类中为内部状态提供了存储空间。通常我们可以结合单例模式来设计具体享元类,为每一个具体享 元类提供唯一的享元对象。

        非享元角色 :并不是所有的抽象享元类的子类都需要被共享,不 能被共享的子类可设计为非共享具体享元类;当需要一个非共享具体享元类的对象时可以直接通过实例化创建。

        享元工厂角色 :负责创建和管理享元角色。当客户对象请求一个享元 对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在 的话,则创建一个新的享元对象

实现

1.创建一个接口public interface Shape {void draw();
}2.创建实现接口的实体类public class Circle implements Shape {private String color;private int x;private int y;private int radius;public Circle(String color){this.color = color;     }public void setX(int x) {this.x = x;}public void setY(int y) {this.y = y;}public void setRadius(int radius) {this.radius = radius;}@Overridepublic void draw() {System.out.println("Circle: Draw() [Color : " + color +", x : " + x +", y :" + y +", radius :" + radius);}
}3.创建一个工厂,生成基于给定信息的实体类的对象import java.util.HashMap;public class ShapeFactory {private static final HashMap<String, Shape> circleMap = new HashMap<>();public static Shape getCircle(String color) {Circle circle = (Circle)circleMap.get(color);if(circle == null) {circle = new Circle(color);circleMap.put(color, circle);System.out.println("Creating circle of color : " + color);}return circle;}
}4.使用该工厂,通过传递颜色信息来获取实体类的对象public class FlyweightPatternDemo {private static final String colors[] = { "Red", "Green", "Blue", "White", "Black" };public static void main(String[] args) {for(int i=0; i < 20; ++i) {Circle circle = (Circle)ShapeFactory.getCircle(getRandomColor());circle.setX(getRandomX());circle.setY(getRandomY());circle.setRadius(100);circle.draw();}}private static String getRandomColor() {return colors[(int)(Math.random()*colors.length)];}private static int getRandomX() {return (int)(Math.random()*100 );}private static int getRandomY() {return (int)(Math.random()*100);}
}

运用场景

        当需要创建大量相似对象时可以使用享元模式,例如游戏中的道具、棋子等。

        当对象需要被共享时,可以使用享元模式,例如线程池中的线程。

        当系统的内存资源相对有限时可以考虑使用享元模式,以减少内存的使用。

        当需要减少对象的创建次数、降低系统开销时可以使用享元模式。

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

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

相关文章

基于springboot的图片文字识别,支持中英文识别

概述 基于springboot的图片文字识别,支持中英文识别. 页面上传图片即可转换为中文或者英文. 详细 1.需求&#xff08;要做什么&#xff09; 识别图片文字, 实现页面上传图片即可转换为中文或者英文. 2.理论概述 OCR&#xff0c;即Optical Character Recognition&#xff…

数据结构与算法:概述

目录 算法 评价标准 时间的复杂度 概念 推导原则 举例 空间的复杂度 定义 情形 运用场景 数据结构 组成方式 算法 在数学领域&#xff0c;算法是解决某一类问题的公式和思想&#xff1b; 计算机科学领域&#xff0c;是指一系列程序指令&#xff0c;用于解决特定的…

数据结构插入排序

好久不见&#xff0c;这几天有点事情&#xff0c;都快一个礼拜没有学习&#xff0c;对键盘都要陌生起来了&#xff0c;今天也是刚刚学了一点排序&#xff0c;在这里也给大家更新一个插入排序&#xff0c;后面也会渐渐的把八大排序更新完的&#xff0c;还有就是二叉树&#xff0…

Vivado 2017.04版本安装教程

文章目录 前言一、vivado 简介二、vivado 下载三、vivado 安装四、vivado 申请证书五、关闭升级提醒六、资源自取 前言 本文记录了在 windows 11 下安装 vivado 2017 的详细步骤。 一、vivado 简介 Vivado 是 Xilinx 公司于 2012 推出的新一代集成设计环境&#xff0c;虽然目…

学习笔记|定时器|STC中断|定时器时间计算|STC32G单片机视频开发教程(冲哥)|第十一集:定时器的作用和意义

文章目录 1.定时器的作用和意义定时器中断定时器是定时器和计数器的统称。 2.STC32G单片机定时器使用原理2.1 先设置功能为定时器/计数器(本质都是加法计数器)2.2、在定时器模式下&#xff0c;设置不分频或者12分频∶Tips&#xff1a;选择不分频还是12分频2.3、定时器的工作模式…

算法竞赛个人注意事项

浅浅记录一下自己在算法竞赛中的注意事项。 数据类 注意看数大小&#xff0c;数学库中的函数尽量加上 * 1.0&#xff0c;转成double&#xff0c;防止整型溢出。&#xff0c;int型相乘如果可能溢出&#xff0c;乘 * 1LL。 数据范围大于1e6&#xff0c;注意用快读。 浮点数输…

HCIP自我重修总笔记

第一章.复习OSITCP/IP 模型 &#xff08;2023 9/5&#xff09; OSI 模型: 开放式系统互联参考模型 应用层&#xff1a;抽象语言-->编码表示层&#xff1a;编码--->二进制会话层&#xff1a;提供会话地址&#xff0c;建立应用程序端到端的会话 上三层为应用程序对数据加…

初识Python

初识Python Python背景知识1. 编程语言2. Python优缺点 搭建Python环境1.找到官网2. 下载3.安装4.检查 安装PyCharm1.找到官网下载2. 安装3. 检查 Python官网文档学习 Python背景知识 1. 编程语言 编程语言通常可以分为以下三类&#xff1a; 高级语言&#xff08;High-Level…

PostgreSQL 查询修改max_connections(最大连接数)及其它配置

文章目录 查询max_connections(最大连接数)修改max_connections(最大连接数)其他配置 查询max_connections(最大连接数) SHOW max_connections;修改max_connections(最大连接数) 要设置PostgreSQL数据库的最大连接数&#xff0c;你需要修改数据库的配置文件 postgresql.conf。…

el-table中加图标文字提示

<el-table :data"tableData" style"width: 100%" max-height"250"><el-table-column fixed prop"aaa" label"日期" width"150" /><el-table-column prop"bbb" label"日期" wi…

【技能树笔记】网络篇——练习题解析(二)

目录 前言 一. 数据链路层的作用 1.1 数据链路层作用 1.2 数据链路层封装 1.3 数据链路层功能 1.4 数据帧格式 二. MAC地址及分类 2.1 MAC地址 2.2 MAC地址分类 三. 交换机的作用 3.1 交换机的作用 3.2 交换机作用 四.交换机的工作原理 4.1 交换机的工作原理 4.…

决策树算法学习笔记

一、决策树简介 首先决策树是一种有监督的机器学习算法&#xff0c;其采用的方法是自顶向下的递归方法&#xff0c;构建一颗树状结构的树&#xff0c;其具有分类和预测功能。其基本思想是以信息熵为度量构造一棵熵值下降最快的树&#xff0c;到叶子节点处的熵值为零。决策树的构…

MVC,MVP,MVVM的理解和区别

MVC MVC &#xff0c;早期的开发架构&#xff0c;在安卓里&#xff0c;用res代表V&#xff0c;activity代表Controller层&#xff0c;Model层完成数据请求&#xff0c;更新操作&#xff0c;activity完成view的绑定&#xff0c;以及业务逻辑的编写&#xff0c;更新view&#xf…

51单片机项目(9)——基于51单片机的电子琴设计

简易电子琴设计设计内容: 1.用矩阵键盘代表琴键&#xff0c;至少能弹出8个音符&#xff0c;分别是:音符1.23.4.,5,6, 2.键按下的时间长短表征节拍的长短&#xff0c;用蜂鸣器发出声音 3.数码管显示出当前音符 4.音量可调 &#xff08;代码及其工程文件放在最后&#xff09; …

pycharm使用

在使用pycharm时&#xff0c;有时一个回车或者一个tab键&#xff0c;缩进的长度不符合预期可以调整设置tab键缩进的长度&#xff1a; 平时工作中&#xff0c;不同的人在编辑代码缩进的时候&#xff0c;有的人喜欢按四个或者六个空格&#xff0c;有的人喜欢按tab键&#xff0c;而…

ostringstream 多线程下性能问题探究

文章目录 背景火焰图ostringstream 的结构引用 背景 在实习过程中&#xff0c;有一个业务场景需要用到 ostringstream&#xff0c;但经过导师提醒&#xff0c;ostringstream 在多线程关系下&#xff0c;竞态消耗较大&#xff0c;但对于当前业务场景&#xff0c;每次操作&#…

使用 Python 的高效相机流

一、说明 让我们谈谈在Python中使用网络摄像头。我有一个简单的任务&#xff0c;从相机读取帧&#xff0c;并在每一帧上运行神经网络。对于一个特定的网络摄像头&#xff0c;我在设置目标 fps 时遇到了问题&#xff08;正如我现在所理解的——因为相机可以用 mjpeg 格式运行 30…

PhpStorm软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 PhpStorm是一款由JetBrains开发的专业PHP集成开发环境&#xff08;IDE&#xff09;&#xff0c;旨在提供全面的PHP开发支持。它是基于IntelliJ IDEA平台构建的&#xff0c;具有强大的功能和工具&#xff0c;可以帮助开发人员提高…

5分钟 将“.py”文件转为“.pyd”文件

代码&#xff1a; from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize import osfile_list os.listdir("./") extensions [] for file in file_list:if file.endswith(".py") and file !…

Unity之3D物理导航系统

一 介绍 Unity自带寻路(导航)系统是unity官方自带的一种寻路系统。我们可以通过它来制作简单的寻路&#xff0c;比如可以制作点击某个位置&#xff0c;让角色自动的绕开障碍走到目标点的效果&#xff0c;比如可以制作敌人AI&#xff0c;让它可以通过NavMesh绕开障碍追击我方单…