设计模式:结构型模式

1. 适配器模式 (Adapter Pattern)

适配器模式是一种结构型设计模式,旨在将一个类的接口转换成客户端所期待的另一个接口,从而使原本由于接口不兼容而无法一起工作的类能够协同工作。适配器模式通常用于需要复用现有类但其接口与要求不匹配的情况。

1.1 适配器模式的概念和作用

适配器模式允许接口不兼容的类可以相互合作,其作用在于解决不同接口之间的兼容性问题,使得原本不兼容的类可以协同工作。它允许我们创建一个包装器 (Adapter),该包装器实现了客户端所期待的目标接口,并将调用转发给被包装对象。

1.2 对象适配器和类适配器的区别

在适配器模式中,有两种常见的实现方式:对象适配器和类适配器。

  • 对象适配器:适配器持有被适配对象的实例,并在适配器中调用被适配对象的方法来实现目标接口。
  • 类适配器:适配器继承了被适配对象,同时实现了目标接口,从而使得适配器可以作为被适配对象的子类被使用。

1.3 适配器模式的结构和实现

适配器模式的结构包括:目标接口 (Target)、适配器 (Adapter)、被适配对象 (Adaptee)。

// 目标接口
interface Target {void request();
}// 被适配对象
class Adaptee {public void specificRequest() {System.out.println("Adaptee's specificRequest called");}
}// 类适配器
class ClassAdapter extends Adaptee implements Target {@Overridepublic void request() {specificRequest();}
}// 对象适配器
class ObjectAdapter implements Target {private Adaptee adaptee;public ObjectAdapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void request() {adaptee.specificRequest();}
}

1.4 适配器模式的优缺点

  • 优点:
    • 使得客户端可以调用不兼容接口的对象。
    • 可以封装已有的类,提高代码复用性。
  • 缺点:
    • 类适配器需要多重继承,不够灵活,只能适配适配者的接口。
    • 对象适配器需要额外的对象引用,增加了系统的复杂度。

1.5 适配器模式在实际项目中的应用场景

适配器模式常用于以下场景:

  • 已有类的接口与现有系统不兼容。
  • 在不破坏封装性的前提下,需要将一个类适配到另一个接口。
  • 需要复用一个类,但其接口与其他类不兼容。

2. 桥接模式 (Bridge Pattern)

桥接模式是一种结构型设计模式,旨在将抽象部分与实现部分分离,使它们可以独立地变化。桥接模式通过将抽象部分和实现部分分开,使它们可以独立地进行扩展和变化,从而降低它们之间的耦合度。

2.1 桥接模式的概念和作用

桥接模式的核心思想是将抽象与实现分离,使它们可以独立变化,相互之间解耦。这样一来,抽象部分和实现部分可以分别进行扩展,而不会相互影响,从而提高了系统的灵活性和可扩展性。

2.2 桥接模式的结构和实现

在桥接模式中,有两个重要的角色:抽象类 (Abstraction) 和实现类 (Implementor)。抽象类定义了抽象部分的接口,而实现类则负责实现抽象部分的具体功能。

// 抽象类
abstract class Abstraction {protected Implementor implementor;public Abstraction(Implementor implementor) {this.implementor = implementor;}public abstract void operation();
}// 实现类接口
interface Implementor {void operationImpl();
}// 具体实现类A
class ConcreteImplementorA implements Implementor {@Overridepublic void operationImpl() {System.out.println("ConcreteImplementorA operationImpl called");}
}// 具体实现类B
class ConcreteImplementorB implements Implementor {@Overridepublic void operationImpl() {System.out.println("ConcreteImplementorB operationImpl called");}
}// 桥接模式的具体实现
class RefinedAbstraction extends Abstraction {public RefinedAbstraction(Implementor implementor) {super(implementor);}@Overridepublic void operation() {implementor.operationImpl();}
}

2.3 桥接模式的优缺点

  • 优点:
    • 分离抽象部分和实现部分,使得系统更加灵活。
    • 可以独立地扩展抽象部分和实现部分。
    • 符合开闭原则,对扩展开放,对修改关闭。
  • 缺点:
    • 增加了系统的复杂度,需要同时设计抽象类和实现类的层次结构。

2.4 桥接模式在实际项目中的应用场景

桥接模式常用于以下场景:

  • 当一个类需要多个变化维度时,使用桥接模式可以将各个维度分离,使得每个维度可以独立变化。
  • 当需要对抽象部分和实现部分进行独立扩展时,可以使用桥接模式。

3. 组合模式 (Composite Pattern)

组合模式是一种结构型设计模式,它允许将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户可以统一对待单个对象和组合对象,从而简化了客户端的代码。

3.1 组合模式的概念和作用

组合模式的核心思想是将对象组织成树形结构,使得客户端可以统一处理单个对象和组合对象。这样一来,用户可以像处理单个对象一样处理组合对象,无需关心其内部结构。

3.2 组合模式的结构和实现

在组合模式中,有两个重要的角色:组件 (Component) 和叶子节点 (Leaf)、容器节点 (Composite)。

// 抽象组件类
interface Component {void operation();
}// 叶子节点类
class Leaf implements Component {@Overridepublic void operation() {System.out.println("Leaf operation called");}
}// 容器节点类
class Composite implements Component {private List<Component> children = new ArrayList<>();public void add(Component component) {children.add(component);}public void remove(Component component) {children.remove(component);}@Overridepublic void operation() {for (Component component : children) {component.operation();}}
}

3.3 组合模式的优缺点

  • 优点:
    • 统一对待单个对象和组合对象,简化了客户端代码。
    • 可以动态地增加或删除组合对象,更灵活。
  • 缺点:
    • 增加了系统的复杂性,需要设计额外的层次结构。
    • 不太容易限制组合对象的类型。

3.4 组合模式在实际项目中的应用场景

组合模式常用于以下场景:

  • 表示树形结构的数据,如文件系统、组织架构等。
  • 图形界面中的布局管理器,将控件组织成嵌套的层次结构。
  • 菜单管理系统,将菜单项和子菜单组织成树形结构。

4. 装饰器模式 (Decorator Pattern)

装饰器模式是一种结构型设计模式,允许向现有对象动态地添加新功能,同时又不改变其结构。这种模式对于扩展类的功能非常有用,同时又保持了类的简单性和可读性。

4.1 装饰器模式的概念和作用

装饰器模式允许在不改变现有对象结构的情况下,动态地添加新功能。它通过创建一个装饰器类,该类包含一个指向原始对象的引用,并实现与原始对象相同的接口。通过将装饰器类的对象包裹在原始对象周围,可以逐步添加新的行为。

4.2 装饰器模式的结构和实现

在装饰器模式中,有以下几个关键角色:组件 (Component)、具体组件 (ConcreteComponent)、装饰器 (Decorator)、具体装饰器 (ConcreteDecorator)。

// 抽象组件类
interface Component {void operation();
}// 具体组件类
class ConcreteComponent implements Component {@Overridepublic void operation() {System.out.println("ConcreteComponent operation called");}
}// 抽象装饰器类
abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}@Overridepublic void operation() {component.operation();}
}// 具体装饰器类
class ConcreteDecorator extends Decorator {public ConcreteDecorator(Component component) {super(component);}@Overridepublic void operation() {super.operation();addedBehavior();}private void addedBehavior() {System.out.println("Added behavior by ConcreteDecorator");}
}

4.3 装饰器模式的优缺点

  • 优点:
    • 可以动态地添加或删除对象的功能,灵活性高。
    • 遵循开闭原则,不需要修改现有代码就可以添加新功能。
  • 缺点:
    • 可能会产生大量的具体装饰器类,增加了系统的复杂性。
    • 客户端需要了解装饰器和被装饰对象的区别,容易混淆。

4.4 装饰器模式在实际项目中的应用场景

装饰器模式常用于以下场景:

  • Java I/O 类库中的 InputStream 和 OutputStream 就是使用了装饰器模式,通过组合不同的装饰器类来实现不同的功能。
  • GUI 应用程序中的窗口和控件,通过装饰器模式可以动态地添加边框、滚动条等装饰。
  • Web 开发中的过滤器、拦截器等功能,也可以使用装饰器模式来实现。

5. 外观模式 (Facade Pattern)

外观模式是一种结构型设计模式,提供了一个统一的接口,用于访问子系统中的一群接口。它隐藏了子系统的复杂性,使得客户端更加容易使用。

5.1 外观模式的概念和作用

外观模式的核心思想是提供一个简单的接口,隐藏了系统的复杂性,并将系统的子模块组织成一个更大的系统。这样,客户端只需要与外观对象进行交互,而不需要了解内部子系统的细节。

5.2 外观模式的结构和实现

在外观模式中,有以下几个关键角色:外观 (Facade)、子系统 (Subsystem)。

// 子系统类
class Subsystem1 {public void operation1() {System.out.println("Subsystem1 operation");}
}class Subsystem2 {public void operation2() {System.out.println("Subsystem2 operation");}
}class Subsystem3 {public void operation3() {System.out.println("Subsystem3 operation");}
}// 外观类
class Facade {private Subsystem1 subsystem1;private Subsystem2 subsystem2;private Subsystem3 subsystem3;public Facade() {subsystem1 = new Subsystem1();subsystem2 = new Subsystem2();subsystem3 = new Subsystem3();}public void operation() {subsystem1.operation1();subsystem2.operation2();subsystem3.operation3();}
}

5.3 外观模式的优缺点

  • 优点:
    • 简化了客户端与子系统之间的交互,降低了耦合度。
    • 客户端不需要了解子系统的内部结构,减少了对子系统的直接依赖。
    • 提高了代码的灵活性和可维护性。
  • 缺点:
    • 如果外观对象过于臃肿,可能会变得难以维护和理解。

5.4 外观模式在实际项目中的应用场景

外观模式常用于以下场景:

  • 复杂系统的接口简化:当一个系统包含多个子系统,并且子系统之间存在复杂的依赖关系时,可以使用外观模式来简化客户端与系统之间的交互。
  • 封装不稳定的接口:当一个系统中的某些接口频繁变化,但是客户端不希望因此受到影响时,可以使用外观模式来封装这些不稳定的接口。

6. 享元模式 (Flyweight Pattern)

享元模式是一种结构型设计模式,旨在通过共享对象来最小化内存使用和提高性能。它适用于大量相似对象的场景,通过共享内部状态来减少内存占用。

6.1 享元模式的概念和作用

享元模式的核心思想是共享对象以减少内存占用和提高性能。在享元模式中,对象分为内部状态和外部状态。内部状态是可以共享的,而外部状态是不可共享的。通过共享内部状态,可以减少系统中重复对象的数量,从而节省内存。

6.2 享元模式的结构和实现

在享元模式中,有以下几个关键角色:享元工厂 (FlyweightFactory)、具体享元 (ConcreteFlyweight)、非共享具体享元 (UnsharedConcreteFlyweight)、享元接口 (Flyweight)。

// 享元接口
interface Flyweight {void operation();
}// 具体享元
class ConcreteFlyweight implements Flyweight {private String intrinsicState;public ConcreteFlyweight(String intrinsicState) {this.intrinsicState = intrinsicState;}@Overridepublic void operation() {System.out.println("ConcreteFlyweight: Intrinsic State = " + intrinsicState);}
}// 享元工厂
class FlyweightFactory {private Map<String, Flyweight> flyweights = new HashMap<>();public Flyweight getFlyweight(String key) {if (!flyweights.containsKey(key)) {flyweights.put(key, new ConcreteFlyweight(key));}return flyweights.get(key);}
}

6.3 享元模式的优缺点

  • 优点:
    • 减少内存占用:通过共享内部状态,可以减少系统中重复对象的数量,节省内存空间。
    • 提高性能:由于减少了对象数量,可以提高系统的性能。
  • 缺点:
    • 增加了系统复杂性:引入了共享对象的管理机制,增加了系统的复杂度。
    • 限制外部状态:外部状态不可共享,可能导致一些不便之处。

6.4 享元模式在实际项目中的应用场景

享元模式常用于以下场景:

  • 文字编辑器中的字符共享:在文字编辑器中,如果存在大量相同字符,可以使用享元模式共享这些字符对象,减少内存占用。
  • 棋盘游戏中的棋子管理:在棋盘游戏中,如果存在大量相同的棋子对象,可以使用享元模式共享这些棋子对象,提高性能。

7. 代理模式 (Proxy Pattern)

代理模式是一种结构型设计模式,用于控制对其他对象的访问。

7.1 代理模式的概念和作用

代理模式充当了客户端和目标对象之间的中介,控制对目标对象的访问。它通常用于以下情况:

  • 远程代理:控制对远程对象的访问,例如在网络上访问对象。
  • 虚拟代理:延迟加载目标对象,直到真正需要时才创建。
  • 保护代理:控制对目标对象的访问权限,验证客户端的请求是否合法。
  • 缓存代理:为昂贵的操作结果提供缓存,避免重复计算。

7.2 静态代理和动态代理的区别

  • 静态代理:在编译时已经确定代理类和目标类的关系,代理类需要显式地实现与目标类相同的接口或继承相同的父类。缺点是每个代理类只能代理一个目标类,不够灵活。
  • 动态代理:在运行时动态生成代理类,无需提前定义代理类。Java中的动态代理是通过 java.lang.reflect.Proxy 类实现的,可以代理任意接口。相比静态代理更灵活,但性能上略有损失。

7.3 代理模式的结构和实现

代理模式通常包含以下角色:

  • 抽象主题 (Subject):定义了代理类和真实主题类的公共接口,客户端通过此接口访问真实主题。
  • 真实主题 (Real Subject):实现了抽象主题接口,是代理模式中的实际业务逻辑。
  • 代理类 (Proxy):保存了一个真实主题对象的引用,可以控制对真实主题的访问,在必要时创建或删除真实主题对象。

示例代码:

// 抽象主题
interface Subject {void request();
}// 真实主题
class RealSubject implements Subject {public void request() {System.out.println("RealSubject: Handling request.");}
}// 代理类
class Proxy implements Subject {private RealSubject realSubject;public Proxy() {this.realSubject = new RealSubject();}public void request() {System.out.println("Proxy: Pre-processing request.");realSubject.request();System.out.println("Proxy: Post-processing request.");}
}

7.4 代理模式的优缺点

优点

  • 可以实现对目标对象的控制,保护目标对象和客户端的透明性。
  • 可以实现远程代理、虚拟代理、保护代理等多种功能。

缺点

  • 由于增加了代理类,可能导致代码结构复杂化。
  • 静态代理需要提前定义代理类,不够灵活;动态代理性能稍逊于静态代理。

7.5 代理模式在实际项目中的应用场景

  • 对外服务接口的访问控制与权限验证。
  • 远程接口的访问与数据传输。
  • 延迟加载大对象或耗时操作。

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

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

相关文章

Qt SQLite的创建和使用

重点&#xff1a; 1.SQLite创建数据库内容方法 链接&#xff1a;SQLite Expert Personal的简单使用-CSDN博客 2.和数据库进行链接方法 QSqlDatabase DB; //数据库连接bool MainWindow::openDatabase(QString aFile) {DBQSqlDatabase::addDatabase("QSQLITE"); /…

使用uniapp开发时自定义tabbar

预览图&#xff1a; 一、配置page.jsong中的tabbar&#xff08;这一步是必须的&#xff0c;因为我们在使用uni.switchTab()时必须要用到&#xff09; "tabBar": {"list": [{"pagePath": "pages/index/index","iconPath": &…

java回顾总结--代理模式

目录 一、代理模式1.1 静态代理示例 1.2 动态代理示例 二、总结 一、代理模式 1.1 静态代理 代理模式给某一个对象提供一个代理对象&#xff0c;并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。比如你按照小卡片上的电话打过去寻求服务&#…

C# 学习第四弹——字符串

一、char类型的使用 字符使用单引号&#xff0c;单个字符 转义字符是一种特殊的字符变量&#xff0c;以反斜线开头&#xff0c;后跟一个或多个字符。 输出多级目录可以使用 二、字符串的声明和初始化 1、引用字符串常量 引用字符串常量初始化——字符使用单引号&#xff0…

加密与安全_探索常用编码算法

文章目录 概述什么是编码编码分类ASCII码 &#xff08;最多只能有128个字符&#xff09;Unicode &#xff08;用于表示世界上几乎所有的文字和符号&#xff09;URL编码 &#xff08;解决服务器只能识别ASCII字符的问题&#xff09;实现&#xff1a;编码_URLEncoder实现&#xf…

K8S常用kubectl命令汇总(持续更新中)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

【Prometheus】基于Altertmanager发送告警到多个接收方、监控各种服务、pushgateway

基于Altertmanager发送报警到多个接收方 一、配置alertmanager-发送告警到qq邮箱1.1、告警流程1.2、告警设置【1】邮箱配置【2】告警规则配置【3】 部署prometheus【4】部署service 二、配置alertmanager-发送告警到钉钉三、配置alertmanager-发送告警到企业微信3.1、注册企业微…

量子算法入门—4.量子比特与量子门(1)

1.量子比特 经典比特和量子比特 经典比特只有0、1两种取值&#xff0c;非黑即白&#xff0c;有n位即 2 n 2^n 2n种可能量子比特使用0、1的量子态描述量子比特的状态&#xff0c;可以通过线性组合形成新的量子态&#xff0c;就像光谱可以调节成分 引入线代记法&#xff0c;0、…

ARK:《BIG IDEAS 2024》

Cathie Wood所带领的方舟投资&#xff08;ARK&#xff09;发布了年度重磅研究报告《BIG IDEAS 2024》&#xff0c;该报告指出人工智能、公共区块链、多组学测序、能源存储和机器人技术这五大板块的融合将带来全球经济活动的改变。 这五个创新平台正在融合并定义这个技术时代&am…

92. 递归实现指数型枚举 刷题笔记

思路 dfs 考虑选或者不选每个位置 用0表示未考虑 1表示选 2表示不选 用u表示搜索状态 u>n时 已经搜到底层了 需要输出当前方案 遍历 如果选了则输出 #include<iostream> using namespace std; int n; const int N16; int st[N]; void dfs(int u){ //u来记…

Git自动忽略dll文件的问题

检查了半天发现是sourcetreee的全局忽略文件导致&#xff0c; 从里面删除dll即可。 我是干脆直接删了全局忽略&#xff0c;太恶心了&#xff0c;如下&#xff1a; #ignore thumbnails created by windows Thumbs.db #Ignore files build by Visual Studio *.exe .vsconfig .s…

fastAdmin表格列表的功能

更多文章&#xff0c;请关注&#xff1a;fastAdmin后台功能详解 | 夜空中最亮的星 FastAdmin是一款基于ThinkPHP5Bootstrap的极速后台开发框架。优点见开发文档 介绍 - FastAdmin框架文档 - FastAdmin开发文档 在这里上传几张优秀的快速入门图: 一张图解析FastAdmin中的表格列…

Linux网络编程(四-TCP协议)

目录 一、TCP概念 二、TCP的首部格式 三、TCP可靠传输机制 3.1 确认应答机制 3.2 超时重传机制 3.3 连接管理 3.3.1 三次握手 3.3.2 四次挥手 3.4 流量控制 3.5 拥塞控制 四、TCP效率机制 4.1 滑动窗口 4.2 重发控制 4.3 延迟应答 4.4 捎带应答 五、TCP的…

大数据分布式计算工具Spark实战讲解(数据输入实战)

Python数据容器转RDD对象 PySpark支持通过SparkContext对象的parallelize成员方法&#xff0c;将&#xff1a; - list - tuple - set - dict - str 转换为PySpark的RDD对象 注意&#xff1a; •字符串会被拆分出1个个的字符&#xff0c;存入RDD对象 •字典仅有key会被存入…

问题:输入git命令出现END命令,按住ctrl+c都没有不能退出,只能输入q才能退出

当输入git命令时&#xff0c;例如git log&#xff0c;会直接出现END这种黑框&#xff0c;按住ctrlc都不能退出&#xff0c;只能通过输入q才能退出的情况 解决方法&#xff1a; git config --global core.pager

Open Harmony开发之分布式账本

简介 Demo基于Open Harmony系统使用ETS语言进行编写&#xff0c;本Demo主要通过设备认证、分布式拉起、分布式数据管理等功能来实现。 应用效果 设备认证,获取同一个局域网内的设备ID&#xff0c;并拉起应用 添加数据并在另一台设备显示该数据 开发步骤 1.新建Openharmony…

安卓使用okhttpfinal下载文件,附带线程池下载使用

1.导入okhttp包 implementation cn.finalteam:okhttpfinal:2.0.7 2.单个下载 package com.example.downloading;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.util.Log; import android.view.View;import java.io.File;import c…

[java] 23种设计模式之装饰者模式

1.1 装饰者模式的概念 ​ 1、在不必改变原类文件和使用继承的情况下&#xff0c;动态地扩展一个对象的功能。它是通过创建一个包装对象&#xff0c;也就是装饰来包裹真实的对象。 ​ 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。装饰对象可以在转发这些…

Gitlab部署管理

一、安装 1.docker安装gitlab sudo docker run -d \-p 6080:80 -p 6022:22 \--name gitlab \--restart always \-v /srv/gitlab/config:/etc/gitlab \-v /srv/gitlab/logs:/var/log/gitlab \-v /srv/gitlab/data:/var/opt/gitlab \gitlab/gitlab-ce:latest2.存储说明 存储应…

大数据分布式计算工具Spark数据计算实战讲解(map方法,flatmap方法,reducebykey方法)

数据计算 map方法 PySpark的数据计算&#xff0c;都是基于RDD对象来进行的&#xff0c;那么如何进行呢&#xff1f; 自然是依赖&#xff0c;RDD对象内置丰富的&#xff1a;成员方法&#xff08;算子&#xff09; 功能&#xff1a;map算子&#xff0c;是将rdd的数据一条条处…