结构型设计模式详解与总结

一、什么是结构型设计模式

结构型设计模式的主要目的是处理类或对象之间的组合与继承问题,通过组织类和对象来形成更大的结构,帮助我们更好地解决类与类、对象与对象之间的耦合问题。这类模式通过定义如何组合对象来实现新的功能,着重于解决系统中复杂关系的组织和维护,使得系统更加易于扩展和维护。

结构型设计模式主要有以下几种:

  1. 适配器模式(Adapter)
  2. 桥接模式(Bridge)
  3. 装饰者模式(Decorator)
  4. 组合模式(Composite)
  5. 外观模式(Facade)
  6. 享元模式(Flyweight)
  7. 代理模式(Proxy)

接下来,我们将逐一讲解这些结构型设计模式。

二、适配器模式(Adapter Pattern)

2.1 模式介绍

适配器模式将一个类的接口转换成客户端所期待的另一个接口,使原本接口不兼容的类可以一起工作。通过这种模式,开发者无需修改已有代码便能使旧系统与新系统兼容。

2.2 模式结构

适配器模式主要有三个参与者:

  • 目标接口(Target Interface):定义客户端所期待的接口。
  • 适配者类(Adaptee):现有接口,但与目标接口不兼容。
  • 适配器(Adapter):实现目标接口,内部封装适配者类,将适配者的接口转换为目标接口。

2.3 代码示例

// 目标接口
public interface Target {void request();
}// 适配者类
public class Adaptee {public void specificRequest() {System.out.println("调用适配者类中的方法");}
}// 适配器类
public class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void request() {adaptee.specificRequest();}
}// 客户端代码
public class Client {public static void main(String[] args) {Adaptee adaptee = new Adaptee();Target target = new Adapter(adaptee);target.request();}
}

2.4 优缺点

  • 优点

    • 可以让不兼容的类协同工作,不用修改现有类,符合开闭原则。
    • 提高了类的复用性和灵活性。
  • 缺点

    • 增加了系统的复杂性,特别是在过多使用适配器的情况下,代码可读性可能降低。

2.5 适用场景

  • 现有系统的接口不符合需求,且无法修改现有系统时。
  • 希望复用一些现有的类,但这些类的接口与目标接口不兼容。

三、桥接模式(Bridge Pattern)

3.1 模式介绍

桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。这种模式通常用于系统有多个维度的变化时,利用组合而不是继承来应对变化。

3.2 模式结构

桥接模式主要由以下几个角色组成:

  • 抽象类(Abstraction):定义抽象部分的接口,包含一个实现类对象。
  • 扩展抽象类(Refined Abstraction):是抽象类的子类,实现具体的业务方法。
  • 实现类接口(Implementor):定义实现类的接口。
  • 具体实现类(Concrete Implementor):实现 Implementor 接口,负责具体的业务逻辑。

3.3 代码示例

// 实现类接口
public interface Implementor {void operationImpl();
}// 具体实现类A
public class ConcreteImplementorA implements Implementor {@Overridepublic void operationImpl() {System.out.println("具体实现类A的操作");}
}// 具体实现类B
public class ConcreteImplementorB implements Implementor {@Overridepublic void operationImpl() {System.out.println("具体实现类B的操作");}
}// 抽象类
public abstract class Abstraction {protected Implementor implementor;public Abstraction(Implementor implementor) {this.implementor = implementor;}public abstract void operation();
}// 扩展抽象类
public class RefinedAbstraction extends Abstraction {public RefinedAbstraction(Implementor implementor) {super(implementor);}@Overridepublic void operation() {implementor.operationImpl();}
}// 客户端代码
public class Client {public static void main(String[] args) {Implementor implementorA = new ConcreteImplementorA();Abstraction abstraction = new RefinedAbstraction(implementorA);abstraction.operation();Implementor implementorB = new ConcreteImplementorB();abstraction = new RefinedAbstraction(implementorB);abstraction.operation();}
}

3.4 优缺点

  • 优点

    • 抽象和实现分离,避免了继承层次的急剧膨胀,支持系统的多维度扩展。
    • 提高了系统的扩展性,增加新的实现类或抽象类都非常方便。
  • 缺点

    • 增加了系统的复杂性,理解和实现桥接模式需要额外的努力。

3.5 适用场景

  • 系统需要从多个维度进行扩展时,比如需要在不同平台上显示不同格式的图形。
  • 希望减少子类的数量,减少类的层次结构。

四、装饰者模式(Decorator Pattern)

4.1 模式介绍

装饰者模式动态地给对象添加额外的职责,相比于继承,装饰者模式更加灵活。装饰者模式通过创建一系列装饰类来对原始对象进行增强,使得对象可以灵活地进行扩展。

4.2 模式结构

装饰者模式包括以下角色:

  • 组件接口(Component):定义对象的基本接口。
  • 具体组件(Concrete Component):实现 Component 接口,代表被装饰的对象。
  • 装饰者(Decorator):实现 Component 接口,并持有一个 Component 对象,负责对其进行增强。
  • 具体装饰者(Concrete Decorator):具体实现装饰者逻辑,增强 Component 对象的功能。

4.3 代码示例

// 组件接口
public interface Component {void operation();
}// 具体组件
public class ConcreteComponent implements Component {@Overridepublic void operation() {System.out.println("执行具体组件的操作");}
}// 装饰者类
public class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}@Overridepublic void operation() {component.operation();}
}// 具体装饰者A
public class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}@Overridepublic void operation() {super.operation();addedBehavior();}// 添加新的行为private void addedBehavior() {System.out.println("具体装饰者A的额外行为");}
}// 具体装饰者B
public class ConcreteDecoratorB extends Decorator {public ConcreteDecoratorB(Component component) {super(component);}@Overridepublic void operation() {super.operation();System.out.println("具体装饰者B的额外行为");}
}// 客户端代码
public class Client {public static void main(String[] args) {Component component = new ConcreteComponent();Component decoratorA = new ConcreteDecoratorA(component);Component decoratorB = new ConcreteDecoratorB(decoratorA);decoratorB.operation();}
}

4.4 优缺点

  • 优点

    • 动态地给对象添加新功能,遵循开闭原则。
    • 装饰者模式可以灵活组合功能,使得每个装饰者类的职责单一,增强了可维护性。
  • 缺点

    • 装饰者模式会增加系统的复杂性,特别是在多个装饰者叠加时,代码的调试可能变得困难。

4.5 适用场景

  • 需要动态地给一个对象添加额外功能,且这些功能可以灵活地组合。
  • 希望避免通过继承来扩展对象的功能时。

五、组合模式(Composite Pattern)

5.1 模式介绍

组合模式将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得客户端对单个对象和组合对象的使用具有一致性,常用于表示层次结构的场景。

5.2 模式结构

组合模式包括以下角色:

  • 组件(Component):为组合中的对象声明接口,并提供了子类的默认行为。
  • 叶子(Leaf):代表组合中的叶子对象,没有子节点。
  • 组合(Composite):定义有子节点的组合对象,并实现与叶子节点一致的接口。

5.3 代码示例

// 组件接口
public abstract class Component {public void add(Component component) {throw new UnsupportedOperationException();}public void remove(Component component) {throw new UnsupportedOperationException();}public Component getChild(int i) {throw new UnsupportedOperationException();}public abstract void operation();
}// 叶子对象
public class Leaf extends Component {@Overridepublic void operation() {System.out.println("执行叶子的操作");}
}// 组合对象
public class Composite extends Component {private List<Component> children = new ArrayList<>();@Overridepublic void add(Component component) {children.add(component);}@Overridepublic void remove(Component component) {children.remove(component);}@Overridepublic Component getChild(int i) {return children.get(i);}@Overridepublic void operation() {for (Component child : children) {child.operation();}}
}// 客户端代码
public class Client {public static void main(String[] args) {Composite root = new Composite();root.add(new Leaf());Composite subComposite = new Composite();subComposite.add(new Leaf());root.add(subComposite);root.operation();}
}

5.4 优缺点

  • 优点

    • 组合模式能清晰地描述对象层次结构,使得客户代码可以一致地操作单个对象和组合对象。
    • 容易扩展新的类型,符合开闭原则。
  • 缺点

    • 设计的层次结构复杂,可能会导致难以维护,特别是在层次过深的情况下。

5.5 适用场景

  • 需要表示对象的部分-整体层次结构时。
  • 希望客户端可以忽略组合对象与单个对象的区别,统一处理它们时。

六、外观模式(Facade Pattern)

6.1 模式介绍

外观模式为子系统中的一组接口提供一个一致的接口,使得子系统更加容易被使用。它通过将复杂的子系统与客户端之间的交互封装起来,简化了客户端的使用难度。

6.2 模式结构

外观模式由以下角色组成:

  • 外观(Facade):提供了与客户端交互的简化接口。
  • 子系统类(Subsystem Classes):复杂的子系统,负责实现子系统的具体功能。

6.3 代码示例

// 子系统A
public class SubsystemA {public void operationA() {System.out.println("子系统A的操作");}
}// 子系统B
public class SubsystemB {public void operationB() {System.out.println("子系统B的操作");}
}// 外观类
public class Facade {private SubsystemA subsystemA;private SubsystemB subsystemB;public Facade() {subsystemA = new SubsystemA();subsystemB = new SubsystemB();}public void operation() {subsystemA.operationA();subsystemB.operationB();}
}// 客户端代码
public class Client {public static void main(String[] args) {Facade facade = new Facade();facade.operation();}
}

6.4 优缺点

  • 优点

    • 简化了复杂系统的使用,使得系统的交互更加清晰明了。
    • 外观模式提供了子系统和客户端之间的松耦合,增强了系统的可维护性。
  • 缺点

    • 增加了额外的外观类,可能会使系统变得臃肿。

6.5 适用场景

  • 需要简化子系统的复杂交互时。
  • 子系统与客户端之间需要松耦合时。

七、享元模式(Flyweight Pattern)

7.1 模式介绍

享元模式通过共享对象来尽量减少内存消耗,特别适用于大量细粒度对象的场景。它通过将相同的对象共享来减少对象数量,以节省内存。

7.2 模式结构

享元模式主要有以下角色:

  • 享元接口(Flyweight Interface):定义享元对象的接口。
  • 具体享元(Concrete Flyweight):实现享元接口,表示可以共享的对象。
  • 非共享享元(Unshared Flyweight):不可以共享的对象。
  • 享元工厂(Flyweight Factory):负责管理享元对象的创建和缓存,确保每个享元对象可以被共享。

7.3 代码示例

// 享元接口
public interface Flyweight {void operation(String externalState);
}// 具体享元
public class ConcreteFlyweight implements Flyweight {private String intrinsicState;public ConcreteFlyweight(String intrinsicState) {this.intrinsicState = intrinsicState;}@Overridepublic void operation(String externalState) {System.out.println("内部状态:" + intrinsicState + ",外部状态:" + externalState);}
}// 享元工厂
public 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);}
}// 客户端代码
public class Client {public static void main(String[] args) {FlyweightFactory factory = new FlyweightFactory();Flyweight flyweight1 = factory.getFlyweight("A");flyweight1.operation("外部状态1");Flyweight flyweight2 = factory.getFlyweight("A");flyweight2.operation("外部状态2");}
}

7.4 优缺点

  • 优点

    • 通过共享对象减少内存消耗,特别适用于有大量重复对象的场景。
    • 提高了系统的性能,减少了内存的使用。
  • 缺点

    • 增加了系统的复杂性,享元对象的状态需要区分内部和外部状态。

7.5 适用场景

  • 系统中有大量相似对象时,且这些对象大部分状态可以共享时。
  • 需要优化内存使用,减少对象数量时。

八、代理模式(Proxy Pattern)

8.1 模式介绍

代理模式为另一个对象提供一个代理对象,代理对象控制着对目标对象的访问,代理模式通过创建一个代理类来实现对原对象的控制,使得原对象不直接暴露给客户端。

8.2 模式结构

代理模式包括以下几个角色:

  • 抽象主题(Subject)

:定义目标对象和代理对象的共同接口。

  • 真实主题(RealSubject):实际的业务实现对象,处理实际的业务逻辑。
  • 代理(Proxy):控制对真实主题的访问,负责在调用真实主题之前进行处理。

8.3 代码示例

// 抽象主题
public interface Subject {void request();
}// 真实主题
public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("真实主题的请求处理");}
}// 代理类
public class Proxy implements Subject {private RealSubject realSubject;@Overridepublic void request() {if (realSubject == null) {realSubject = new RealSubject();}System.out.println("代理类处理前的操作");realSubject.request();System.out.println("代理类处理后的操作");}
}// 客户端代码
public class Client {public static void main(String[] args) {Subject proxy = new Proxy();proxy.request();}
}

8.4 优缺点

  • 优点

    • 代理模式可以在不修改目标对象的前提下,通过代理对象扩展目标对象的功能(如权限控制、日志记录、延迟加载等)。
    • 提供了目标对象的间接访问,客户端无需知道具体的目标对象如何实现,可以通过代理来控制访问。
  • 缺点

    • 增加了系统的复杂性,尤其是在多层代理时,可能会影响系统性能。
    • 代理模式可能会造成过多的代理类,增加系统维护成本。

8.5 适用场景

  • 需要控制对对象的访问时,例如在远程调用、权限控制、缓存机制、延迟加载等场景中。
  • 希望通过代理对象在不修改目标对象的情况下增强某些功能时。

九、总结

在设计模式中,结构型设计模式主要关注类和对象的组合,它们通过一定的组合方式来解决系统的扩展问题,同时也提升了系统的灵活性和可维护性。在实际开发过程中,合理选择和使用结构型设计模式,不仅可以简化系统的复杂度,还能提高系统的可扩展性和可维护性。

  • 适配器模式 用于转换接口,使得不兼容的接口可以一起工作。
  • 桥接模式 通过分离抽象和实现,使得它们可以独立变化。
  • 装饰者模式 动态地为对象添加额外的功能,符合开闭原则。
  • 组合模式 将对象组合成树形结构,以实现部分-整体的层次结构。
  • 外观模式 提供了简化子系统使用的统一接口,降低了系统的复杂度。
  • 享元模式 通过共享细粒度对象来减少内存消耗。
  • 代理模式 通过代理对象控制对目标对象的访问,增加了对目标对象访问的灵活性。

每种设计模式都有其独特的适用场景和优缺点,开发者在项目中选择合适的模式,不仅能够提高开发效率,还能增强系统的稳定性和扩展性。通过对这些结构型设计模式的理解和掌握,能够帮助开发者更好地应对复杂系统设计中的挑战,提升代码的质量和可维护性。

在实际的开发工作中,结构型设计模式常常是结合其他设计模式(如创建型模式、行为型模式)一起使用的,它们并非孤立存在,而是相互补充和增强,共同解决系统设计中的复杂问题。掌握这些模式的精髓,能够让开发者在复杂系统设计中游刃有余,打造出高效、灵活、易扩展的系统架构。


通过本篇对结构型设计模式的介绍和总结,希望读者能够对这些模式有一个清晰的理解和认知,并在实际项目中熟练运用,设计出更加健壮和高效的系统。

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

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

相关文章

AI免费文档处理在线工具:ColPali文本检索文档

1、ColPali 原理还是对比学习&#xff0c;图像和文本&#xff0c;文档通过图像模型&#xff0c;文本通过大模型gemma https://huggingface.co/spaces/manu/ColPali-demo 检索pdf

k8s 中存储之 PV 持久卷 与 PVC 持久卷申请

目录 1 PV 与 PVC 介绍 1.1 PersistentVolume&#xff08;持久卷&#xff0c;简称PV&#xff09; 1.2 PersistentVolumeClaim&#xff08;持久卷声明&#xff0c;简称PVC&#xff09; 1.3 使用了PV和PVC之后&#xff0c;工作可以得到进一步的细分&#xff1a; 2 持久卷实验配置…

深度0.1%调光恒流芯片SL8701支持PWM调光 模拟调光 无频闪 多路共阳

一、芯片概述 SL8701是一款内置100V MOS的降压型高调光比LED恒流驱动芯片&#xff0c;专为智能调光调色照明研发设计。它支持多种调光方式&#xff0c;包括PWM调光和模拟调光&#xff0c;能够实现高调光比&#xff0c;满足不同场景的照明需求。 二、主要特性 PWM调光支持&am…

【Vue3】 h()函数的用法

目录 介绍 参数 使用案例 1.创建虚拟 DOM 元素 2. 组件的动态渲染 3. 创建功能组件 4.渲染动态属性 5. 使用插槽 6. 创建动态标签 介绍 h() 函数用于辅助创建虚拟 DOM 节点&#xff0c;它是 hypescript 的简称——能生成 HTML (超文本标记语言) 的 JavaScript&#x…

Unsupervised HDR Image and Video Tone Mapping via Contrastive Learning

Abstract 捕捉高动态范围 (HDR) 图像&#xff08;视频&#xff09;很有吸引力&#xff0c;因为它可以揭示黑暗和明亮区域的细节。 由于主流屏幕仅支持低动态范围&#xff08;LDR&#xff09;内容&#xff0c;因此需要色调映射算法来压缩HDR图像&#xff08;视频&#xff09;的…

Python编程:创意爱心表白代码集

在寻找一种特别的方式来表达你的爱意吗&#xff1f;使用Python编程&#xff0c;你可以创造出独一无二的爱心图案&#xff0c;为你的表白增添一份特别的浪漫。这里为你精选了六种不同风格的爱心表白代码&#xff0c;让你的创意和情感通过代码展现出来。 话不多说&#xff0c;咱…

Collection-LinkedList源码解析

文章目录 概述LinkedList实现底层数据结构构造函数getFirst(), getLast()removeFirst(), removeLast(), remove(e), remove(index)add()addAll()clear()Positional Access 方法查找操作 概述 LinkedList同时实现了List接口和Deque接口&#xff0c;也就是说它既可以看作一个顺序…

Magnum IO

NVIDIA Magnum IO 文章目录 前言加速数据中心 IO 性能,随时随地助力 AINVIDIA Magnum IO 优化堆栈1. 存储 IO2. 网络 IO3. 网内计算4. IO 管理跨数据中心应用加速 IO1. 数据分析Magnum IO 库和数据分析工具2. 高性能计算Magnum IO 库和 HPC 应用3. 深度学习Magnum IO 库和深度…

ModelMapper的常见用法 ,号称是beanUtils.copyProp....的升级版??,代码复制粘贴即可复现效果,so convenient

官网案例 以下将官网案例做一个解释 1&#xff09;快速入门 递归遍历源对象的属性拷贝给目标对象 拷贝对象下对象的属性值 Data class Order {private Customer customer;private Address billingAddress; }Data class Customer {private Name name; }Data class Name {pr…

【笔记】自动驾驶预测与决策规划_Part5_决策过程(上)

决策过程 0. 前言1.决策过程的引入1.1有了planning&#xff0c;为什么还需要decision-making&#xff1f;1.2 决策规划的一些思考 2.马尔可夫决策过程及其关键要素2.1 马尔可夫过程2.1.1 什么是随机过程&#xff1f;2.1.2 什么是马尔科夫性&#xff1f;2.1.3 马尔可夫决策过程 …

单片机(学习)2024.10.11

目录 按键 按键原理 按键消抖 1.延时消抖 2.抬手检测 通信 1.通信是什么 2.电平信号和差分信号 3.通信的分类 (1)时钟信号划分 同步通信 异步通信 (2)通信方式划分 串行通信 并行通信 (3)通信方向划分 单工 半双工 全双工 4.USART和UART&#xff08;串口通信&a…

计算机毕业设计 基于Python的食品销售数据分析系统的设计与实现 Python毕业设计 Python毕业设计选题 数据分析 Vue【附源码+安装调试】

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

安装R和RStudio:开始你的数据分析之旅

数据分析是当今世界中一个非常热门的领域&#xff0c;而R语言是进行数据分析的强大工具之一。R是一种编程语言和软件环境&#xff0c;用于统计计算和图形表示。RStudio是一个集成开发环境&#xff08;IDE&#xff09;&#xff0c;它为R语言提供了一个更加友好和高效的工作环境。…

从commit校验失效问题探究husky原理

一、背景 之前创建的项目&#xff0c;发现代码 commit 提交的时候没有了任何校验&#xff0c;具体表现&#xff1a; 一是 feat fix 等主题格式校验没有了二是代码 lint 不通过也能提交 尝试解决这个问题&#xff0c;并深入了解husky的实现原理&#xff0c;将相关的一些知识点…

【Canvas与诗词】要做一棵树,站成永恒

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>要做一棵树站成永恒</title><style type"text/css&quo…

tauri开发Mac电脑Safari浏览器一个很奇怪的问题:在 input 输入框输入的是全小写英文字母,会自动将首字母转换为大写解决办法

问题原因 在 Mac 系统中默认使用 Safari 的内核 WKWebView 作为渲染引擎&#xff0c;而 Safari 浏览器的一些 “人性化” 机制&#xff1a;如果输入框中输入的是全小写英文&#xff0c;会自动将首字母转换为大写。 解决办法 我只需要禁止这个默认的行为&#xff0c;即可解决这…

STM32(十八):实时时钟

时间戳 Unix 时间戳&#xff08;Unix Timestamp&#xff09;定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数&#xff0c;不考虑闰秒。 时间戳存储在一个秒计数器中&#xff0c;秒计数器为32位/64位的整型变量。 世界上所有时区的秒计数器相同&#xff0c;不同时…

项目_C_Ncurses_Flappy bird小游戏

Ncurses库 概述 什么是Ncurses库&#xff1a; Ncurses是一个管理应用程序在字符终端显示的函数库&#xff0c;库中提供了创建窗口界面、移动光标、产生颜色、处理键盘按键等功能。 安装Ncurses库&#xff1a; sudo apt-get install libncurses5-dev 头文件与编译&#xf…

ECCV`24 | 新加坡国立华为提出Vista3D: 实现快速且多视角一致的3D生成

文章链接&#xff1a;https://arxiv.org/pdf/2409.12193 gitbub链接&#xff1a;https://github.com/florinshen/Vista3D 亮点直击 提出了Vista3D&#xff0c;一个用于揭示单张图像3D darkside 的框架&#xff0c;能够高效地利用2D先验生成多样的3D物体。开发了一种从高斯投影到…

初级学习:Python实现AI并搭建

随着人工智能(AI)的迅猛发展,越来越多的人希望能够学习如何通过编程实现AI应用。Python,因为其简洁易用,被广泛认为是AI开发的理想编程语言。本文将介绍Python在AI开发中的基础应用,帮助初学者入门并构建自己的AI项目。 为什么选择Python 在了解如何用Python实现AI之前,…