Java 中的适配器 vs 装饰器 vs 门面 vs 代理设计模式
Adapter(适配器)、Decorator(装饰器)、Facade(门面) 和 Proxy(代理) 设计模式之间有一些惊人的相似之处,因为它们都使用组合和委托来解决问题。 适配器模式包装一个接口,并将调用委托给它。 装饰器包装一个对象并在其之上实现行为,Facade 包装一个或多个接口以提供一个易于使用的中央接口,代理模式还包装 Subject 并委托对它的调用。 那么问题来了,为什么会有不同的模式呢? Adapter、Decorator、Facade 或 Proxy 模式之间的区别是什么,如果它们的结构相同。 答案是目的
。 是的,所有这些 Java 设计模式都有相似的结构和类图,但它们的目的却完全不同。
- 适配器模式的主要目的是转换接口。 适配器模式让两个组件一起工作,因为不兼容的接口而无法工作。
- 装饰器模式,在运行时添加新功能。它允许我们丰富对象,即使是在对象创建之后。
- 门面设计模式既不转换接口也不增加新的功能,而只是提供更简单的接口。因此,客户端不是直接访问系统的各个组件,而是使用门面。 门面设计模式允许客户以更简单的界面和更少的工作与复杂的系统进行交互。 然后门面将调用各个组件。
- 代理模式也与适配器和装饰器非常相似,但其目的是控制对象的访问。代理阻止客户端直接访问对象,而是作为一个真实的对象,可以提供替代行为或将请求转发给原始对象。
代理是所有这些模式中最通用的模式,它可以以不同的方式使用,例如用于与远程对象通信的远程代理、用于控制昂贵对象访问的虚拟代理、基于角色提供对对象的访问的保护代理、缓存代理,它可以返回缓存的对象等。
Java 中的适配器、门面、代理和装饰器模式之间的相似之处
主要的相似之处之一是结构,所有这些模式都包装一个对象并委托请求处理或方法调用给它们。 这里还有一些东西,这是所有这些模式之间的共同点。
- 在经典设计模式中,它们都被定义为结构模式,如GOF设计模式。
- 他们都使用组合和委托来实现他们的意图。 适配器使用组合将调用从目标接口转发到 adaptee 接口,装饰器在添加新行为之前也使用相同的技术,Facade 由所有子组件组成,代理也使用组合和委托来转发请求。
- 装饰器和代理模式都意味着停留在原始对象的位置,这就是为什么 装饰器和代理模式都实现了真实对象的接口。 由于这种性质,可以将装饰器和代理传递给接受原始或真实对象的方法。
- 适配器和门面模式,将请求转发到不同的接口,该接口可以是适配器或来自子系统的任何组件接口。
- 适配器和门面模式的另一个相似点是它们可以包装多个接口,这也不同于 装饰器和代理模式,因为它们倾向于对一个对象进行操作。
Java中适配器与装饰器与代理与门面设计模式之间的区别
现在我们知道所有这些结构模式之间有很多相似之处,让我们看看它们之间的一些差异。 正如我之前所说,它们的意图、解决的问题以及使用它们的位置不同。
- 适配器模式转换接口,装饰器模式不转换接口,它只是实现原始对象的接口,这样它就可以传递给一个接受原始对象的方法。 门面和代理模式也不转换接口。
- 装饰器和代理模式之间的主要区别之一是 装饰器从不创建对象,它总是在已经存在的对象上添加新功能,另一方面,代理可以创建一个不存在的对象。 它可以代替一个真实的对象,直到它准备好,然后开始向它转发请求。
- 装饰器设计模式还允许添加多个功能,并且可以通过链接多个装饰器以有序的方式进行,而代理模式不建议代理链接。
- 如果我们比较装饰器和门面模式,那么你可以看到与装饰器不同,门面不添加任何新的行为,它只是从接口调用现有的方法,它作为一个门面提供。
- 与装饰器、代理和适配器设计模式不同,门面不需要实现任何特定的接口。 事实上,门面甚至可以是一个类,只是持有各个子系统组件并提供客户端所需的更简单的操作,然后在子系统上调用相应的方法。
例如,我们可以将 Car 视为门面,它提供了启动和停止的 start()
和 stop()
方法。 当客户端调用 start()
方法时,它可能会通过调用相应的方法来启动各个子系统,例如 engine.start()
, wheels.move()
, lights.on()
, ac.on()
等。
Adapter、Decorator、Proxy和Facade模式的UML图
我们一直在谈论的相似之处在它们的结构中更为明显。 如果查看他们的 UML 图,可以清楚地看到相似之处。
适配器模式的 UML 图
装饰者模式的UML图
代理模式的UML图
Facade模式的UML图
这就是 Java 中适配器 、装饰器 、代理和门面设计模式之间的区别。 了解它们之间的异同将提高大家的知识和发现设计模式使用的能力。 简而言之,如果需要转换接口,请使用适配器设计模式,使两方协同工作。
如果由于各种原因需要隐藏真实对象,则应该在 Java 中使用代理设计模式,例如 安全、性能、网络等。使用装饰器模式在运行时在现有对象上添加新行为,它提供了混合行为并根据客户要求以不同顺序应用它们的灵活性。
最后使用 门面模式为客户端提供复杂系统的简化访问。 门面提供了更高层次的抽象,应该包含客户端所需的操作。
相关文章
使用 Java 在 MongoDB 中生成 ObjectId
发布时间:2023/04/20 浏览次数:179 分类:MongoDB
-
本文将讨论 ObjectId 以及我们如何使用 Java 程序生成它。 为了使主题更简单,我们将看到一个带有解释的示例,以使主题更容易。
在 PHP 变量中存储 Div Id 并将其传递给 JavaScript
发布时间:2023/03/29 浏览次数:69 分类:PHP
-
本文教导将 div id 存储在 PHP 变量中并将其传递给 JavaScript 代码。
如何在 Java 中把日期转换为字符串
发布时间:2023/03/28 浏览次数:192 分类:Java
-
本篇文章介绍了如何在 Java 中把 java.util.Date 转换为字符串 String。