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

news2024/12/24 9:23:27

目录

桥接模式

简介

优缺点

结构

实现

运用场景

组合模式

简介

优缺点

结构

实现

运用场景

享元模式

简介

优缺点

结构

实现

运用场景


桥接模式

简介

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

优缺点

优点:

        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;
   }
 
   @Override
   public 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.coloradmin.cn/o/982506.html

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

相关文章

【rar密码】如何修改rar压缩包密码?

rar压缩包设置了密码&#xff0c;想要修改密码&#xff0c;有方法吗&#xff1f;目前看来&#xff0c;还是没有&#xff0c;我们只输入密码将压缩包中的文件解压出来。 然后将解压出来的文件再重新压缩&#xff0c;重新设置一个密码进行压缩即可达到修改密码的目的了 想要修改密…

leetcode 925. 长按键入

2023.9.7 我的基本思路是两数组字符逐一对比&#xff0c;遇到不同的字符&#xff0c;判断一下typed与上一字符是否相同&#xff0c;不相同返回false&#xff0c;相同则继续对比。 最后要分别判断name和typed分别先遍历完时的情况。直接看代码&#xff1a; class Solution { p…

B094-人力资源项目-微服务授权Oauth2

目录 背景OAUTH2总体流程Oauth2授权码模式oauth2的三方授权流程图案例演示代码讲解-整合oauth2springsecurityjwt先创建一个用于认证的服务增加AuthorizationServerConfig 模块总结认证服务整合zuul获取令牌加入网关后的变化代码详解测试 背景 微服务架构下应用散步在不同的服…

DC电源模块对电磁干扰的影响

BOSHIDA DC电源模块对电磁干扰的影响 DC电源模块是一种常用的电源转换设备&#xff0c;可以将交流电转换成直流电&#xff0c;并通过电路电子元件对电压、电流等参数进行调整&#xff0c;以满足外部设备对电源的需求。然而&#xff0c;由于DC电源模块自身的工作特性&#xff…

Deep Java Library(四)使用DJL Serving部署JAVA模型 For Windows

1.下载Windows版DJL Serving Windows版DJL Serving下载地址&#xff1a; https://publish.djl.ai/djl-serving/serving-0.23.0.zip 下载下来是一个zip压缩包&#xff0c;大约50M左右&#xff0c;目前最新版本为0.23.0 2.安装DJL Serving 解压serving-0.23.0.zip后目录如下 …

网络技术七:命令行基础

命令行操作基础 命令类型 常见设备管理命令 H3C路由交换产品连接方法 使用console线本地连接 协议Serial&#xff0c;接口com口&#xff0c;波特率9600 适用于设备的初次调试 使用Telnet远程访问 适用于设备上架配置好后的维护管理 使用SSH远程访问 数据传输过程加密&…

设计模式系列-外观模式

一、上篇回顾 上篇我们主要讲述了创建型模式中的最后一个模式-原型模式&#xff0c;我们主要讲述了原型模式的几类实现方案&#xff0c;和原型模式的应用的场景和特点&#xff0c;原型模式 适合在哪些场景下使用呢&#xff1f;我们先来回顾一下我们上篇讲述的3个常用的场景。 1…

聚观早报|全球AI领域投资总额暴降;哈啰租车开启假期早鸟预定

【聚观365】9月7日消息 全球AI领域投资总额暴降 哈啰租车开启假期早鸟预定 微信上线“腾讯混元助手”小程序 腾讯“QQ群恢复”功能下线 一嗨租车1.1万个直营网点接入滴滴APP 全球AI领域投资总额暴降 媒体报道称&#xff0c;科技巨头Meta&#xff08;原Facebook&#xff…

TCP/IP基础

前言&#xff1a; TCP/IP协议是计算机网络领域中最基本的协议之一&#xff0c;它被广泛应用于互联网和局域网中&#xff0c;实现了不同类型、不同厂家、运行不同操作系统的计算机之间的相互通信。本文将介绍TCP/IP协议栈的层次结构、各层功能以及数据封装过程&#xff0c;帮助您…

js-14---什么是事件代理?应用场景是什么?

1、事件代理是什么&#xff1f; 事件代理&#xff0c;通俗来讲就是把一个元素响应事件&#xff08;click&#xff0c;keydown…&#xff09;的函数委托到另一个元素。 事件流都会经过三个阶段&#xff1a;捕获阶段–>目标阶段----->冒泡阶段 事件委托就是在冒泡阶段完成&…

Fiddler安装与使用教程(2) —— 软测大玩家

&#x1f60f;作者简介&#xff1a;博主是一位测试管理者&#xff0c;同时也是一名对外企业兼职讲师。 &#x1f4e1;主页地址&#xff1a;【Austin_zhai】 &#x1f646;目的与景愿&#xff1a;旨在于能帮助更多的测试行业人员提升软硬技能&#xff0c;分享行业相关最新信息。…

AI新时代,新华三存储新思考

在数字经济蓬勃发展下&#xff0c;数据正在重塑社会运行模式&#xff0c;推动百行百业的创新发展&#xff0c;成为经济发展的关键驱动力。如今数据成为企业的重要资产&#xff0c;企业希望通过数据了解市场和客户的需求来快速决策&#xff0c;这不仅需要数据高效流转&#xff0…

Python爬取电影信息:Ajax介绍、爬取案例实战 + MongoDB存储

Ajax介绍 Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;是一种用于在Web应用程序中实现异步通信的技术。它允许在不刷新整个网页的情况下&#xff0c;通过在后台与服务器进行数据交换&#xff0c;实时更新网页的一部分。Ajax的主要特点包括&#xff1a; 异步通…

【解决】mysqladmin flush-hosts

问题 mysql出现 mysqladmin flush-hosts&#xff0c;是因为其他客户机连接错误次数过多时&#xff0c;mysql会禁止客户机连接。 解决方法 1、进入服务器数据库&#xff0c;打开数据库命令行界面输入 flush hosts; 此时便可连接 2、可以.修改mysql配置文件&#xff0c;在[…

SpringBoot项目--电脑商城【上传头像】

一、易错点 1.错误写法&#xff1a; 把文件存到数据库中,需要图片时访问数据库,数据库将文件解析为字节流返回,最后写到本地的某一个文件.这种方法太耗费资源和时间了 2.正确写法&#xff1a; 将对应的文件保存在操作系统上,然后再把这个文件路径记录下来,因为在记录路径的…

重生奇迹通关恶魔广场攻略篇

初次进入重生奇迹MU的血色城堡&#xff0c;你可能会对里面不断刷新出来的怪物产生一种密集恐惧症&#xff0c;但是请相信一点&#xff0c;那就是恶魔广场里面的怪物更多&#xff0c;而且品种还不重复&#xff0c;由低至高&#xff0c;轮番刷新&#xff0c;一波又一波……在我看…

Linux部署kettle并设置定时任务

一.安装Kettle linux中使用kettle时首先需要jdk环境&#xff0c;这里就不概述linux中jdk的安装与配置了。 1.首先将kettle压缩包放入linux并解压 unzip data-integration.zip kettle安装路径为:/root/Kettle9.3/data-integration 设置权限 chmod -R 755 /root/Kettle9.3/d…

Allegro画原理图时不能用的非法字符,你知道吗?

Cadence Allegro是一款电子设计自动化工具&#xff0c;常用于原理图绘制和电路设计&#xff0c;在使用Allegro画原理图时&#xff0c;电子工程师可能为了确保文件的准确性和稳定性&#xff0c;能够顺利进行后续的PCB设计和制造&#xff0c;需要注意这些非法字符&#xff0c;那么…

提高 Web 开发效率的10个VS Code扩展插件,你知道吗?

前言 一个出色的开发工具可以显著提高开发人员的开发效率&#xff0c;而优秀的扩展插件则能更进一步地提升工具的效率。在前端开发领域&#xff0c;VSCode毫无疑问是目前最受欢迎的开发工具。为了帮助前端开发人员提高工作效率&#xff0c;今天小编将向大家推荐10个强大的VSCo…

TSINGSEE青犀视频AI智能算法平台电动车入梯检测解决方案

一、方案背景 随着大众的出行要求逐渐提升&#xff0c;交通拥堵现象也随处可见&#xff0c;电动车出行&#xff0c;就成了大家的首选。随着电动车数量的激增&#xff0c;众多用户为了个人方便&#xff0c;大多在室内停放或充电&#xff0c;有的甚至停放在走道、楼梯间等公共区…