专栏名称: 前端早读课
我们关注前端,产品体验设计,更关注前端同行的成长。 每天清晨五点早读,四万+同行相伴成长。
目录
相关文章推荐
桦爸聊升学  ·  考研后闪电留学一站式解读20241224(一) ·  昨天  
桦爸聊升学  ·  考研后闪电留学一站式解读20241224(一) ·  昨天  
前端早读课  ·  【早阅】适配器和组合设计模式 ·  昨天  
前端早读课  ·  【第3435期】构建更高效的 React ... ·  2 天前  
言鼎动作学苑  ·  FMS课堂实录-张丹玥 | FMS 筛查的次数 ·  3 天前  
言鼎动作学苑  ·  FMS课堂实录-张丹玥 | FMS 筛查的次数 ·  3 天前  
前端之巅  ·  快手前端动效大揭秘:告别低效,vision平 ... ·  5 天前  
51好读  ›  专栏  ›  前端早读课

【早阅】适配器和组合设计模式

前端早读课  · 公众号  · 前端  · 2024-12-24 08:00

正文

作者:@Agbo, Daniel Onuoha
原文:https://dev.to/shieldstring/adapter-and-composite-design-patterns-4701

背景

在软件工程中,设计模式是解决常见问题的可重用解决方案。结构型设计模式专注于如何将类和对象组合成更大的结构。本文深入探讨了两种常见的结构型设计模式:适配器模式(Adapter Pattern)和组合模式(Composite Pattern)。这两种模式在处理不同类型的软件设计问题时非常有用,尤其是在需要灵活性和统一性的场景中。

要点

1、适配器模式

用于将一个现有类的接口转换成系统期望的接口, 充当了两个不兼容接口之间的桥梁, 使它们能够协同工作。

2、组合模式:用于以统一的方式处理单个对象和对象组合。此模式允许你构建表示部分 - 整体层次结构的树状结构, 其中叶对象和组合对象都被客户端以相同的方式对待。

分析

1、适配器模式

场景

当你需要将第三方库或遗留系统集成到当前代码中, 但第三方代码的接口与系统期望的接口不匹配时, 适配器模式可以帮助你 "适配" 现有代码以满足新系统的要求, 同时无需修改原始代码。

【第2896期】插件化设计模式在前端领域的应用

关键组件

  • 客户端 (Client): 需要特定功能但期望特定接口的系统或应用程序。

  • 适配者 (Adaptee): 提供所需功能但接口不匹配的现有类或系统。

  • 适配器 (Adapter): 将适配者的接口转换为客户端期望的接口的类。

示例

假设你有一个通过 PayPal 处理支付的现有类, 但现在需要将其集成到一个期望 Stripe 支付接口的系统中。以下是适配器模式如何提供帮助:

 // Adaptee: 现有的 PayPal 支付系统
class PayPalPayment {
pay(amount) {
console.log(`Paying $${amount} using PayPal.`);
}
}

// Target Interface: 系统期望的类似 Stripe 的支付接口
class StripePayment {
processPayment(amount) {
console.log(`Paying $${amount} using Stripe.`);
}
}

// Adapter: 将 PayPal 适配到 Stripe 的接口
class PayPalAdapter extends StripePayment {
constructor(paypal) {
super();
this.paypal = paypal;
}

processPayment(amount) {
this.paypal.pay(amount);
}
}

// Client: 使用 StripePayment 接口
const paymentSystem = new PayPalAdapter(new PayPalPayment());
paymentSystem.processPayment(100);

适配器模式的优势

  • 灵活性:你可以重用现有类而无需修改其代码, 这在使用第三方库时非常有用。

  • 单一职责原则:适配器模式允许清晰地分离关注点。适配器专注于转换接口, 而客户端和适配者则执行各自的角色。

  • 松耦合:客户端和适配者是松耦合的, 允许你轻松地替换或升级组件。

何时使用

  • 当你需要将遗留代码集成到新系统中时。

  • 当你的系统期望一个特定的接口, 但可用的组件没有提供该接口时。

2、组合模式

场景

假设你正在设计一个图形编辑器, 用户可以在其中绘制基本形状(如圆形和矩形)并将它们组合成更复杂的形状。复杂形状由单个形状组成, 但你希望以相同的方式处理单个形状和组合形状。

【图书】漫画设计模式

关键组件

  • 组件 (Component): 声明单个对象和组合对象的通用操作的接口。

  • 叶 (Leaf): 实现组件接口的单个对象。这些是基本构建块(例如, 单个形状)。

  • 组合 (Composite): 保存多个叶对象的 对象。组合也实现了组件接口, 允许客户端将其视为叶对象。

示例

让我们以图形编辑器示例为例, 在该示例中, 我们希望以统一的方式处理单个形状和形状组:

 // Component:  单个对象和组合对象的通用接口
class Graphic {
draw() {}
}

// Leaf: 表示单个形状
class Circle extends Graphic {
draw() {
console.log(" Drawing a Circle ");
}
}

class Rectangle extends Graphic {
draw() {
console.log(" Drawing a Rectangle ");
}
}

// Composite: 表示形状组
class CompositeGraphic extends Graphic {
constructor() {
super();
this.graphics = [];
}

add(graphic) {
this.graphics.push(graphic);
}

remove(graphic) {
this.graphics = this.graphics.filter(g => g !== graphic);
}

draw() {
for (const graphic of this.graphics) {
graphic.draw();
}
}
}

// Client: 使用单个对象和组合对象
const circle = new Circle();
const rectangle = new Rectangle();
const composite = new CompositeGraphic();
composite.add(circle);
composite.add(rectangle);
composite.draw(); // 输出: Drawing a Circle, Drawing a Rectangle

组合模式的优势

  • 一致性:组合模式允许客户端以统一的方式处理单个对象和组合。你可以以相同的方式处理叶对象和组合对象, 而无需编写条件代码。

  • 简化客户端代码:由于单个对象和组合对象共享相同的接口, 因此客户端代码变得更简单, 更易于管理。

  • 可扩展性:通过添加新的叶或组合组件可以轻松扩展系统, 而不会影响客户端代码。

何时使用

  • 当你需要表示部分 - 整体层次结构时, 例如文件系统中的文件和文件夹或图形编辑器中的形状。

  • 当你希望客户端以统一的方式处理单个对象和组合时。

结论

适配器模式和组合模式是软件开发中非常重要的工具,尤其是在需要灵活性和统一性的场景中。适配器模式适用于集成不兼容的接口,而组合模式则适用于处理树形结构。理解和应用这些模式可以显著提高应用程序的可维护性、灵活性和可扩展性,是构建健壮软件系统的关键。

😀 每天只需花五分钟即可阅读到的技术资讯,加入【早阅】共学,可联系 vx:zhgb_f2er

5 分钟新知:了解技术资讯的一种方式。

🚀可直接通过阅读原文了解详细内容。