【愚公系列】2023年10月 二十三种设计模式(七)-桥接模式(Bridge Pattern)

举报
愚公搬代码 发表于 2021/12/04 18:39:03 2021/12/04
【摘要】 设计模式(Design Pattern)是软件开发领域的宝贵经验,是多人反复借鉴和广泛应用的代码设计指导。它们是一系列经过分类和归纳的代码组织方法,旨在实现可重用性、可维护性和可理解性。使用设计模式,我们能够编写高质量的代码,使其更易于他人理解,并提供了代码可靠性的保证。

🏆 作者简介,愚公搬代码
🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。
🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏

🚀前言

设计模式(Design Pattern)是软件开发领域的宝贵经验,是多人反复借鉴和广泛应用的代码设计指导。它们是一系列经过分类和归纳的代码组织方法,旨在实现可重用性、可维护性和可理解性。使用设计模式,我们能够编写高质量的代码,使其更易于他人理解,并提供了代码可靠性的保证。

毫无疑问,设计模式对个人、团队和整个系统都带来了显著的益处。它们将代码开发提升到工程化水平,为软件工程构建提供了坚实的基础,就如同大厦的一块块精巧的砖石一样。在项目中明智地应用设计模式可以完美地解决各种复杂问题。每种设计模式都有相应的原理和最佳实践,它们描述了我们日常开发中不断遇到的问题,以及这些问题的核心解决方法。正是因为这种实用性和通用性,设计模式才能在软件开发中广泛地得以应用。设计模式是构建稳健、可扩展和可维护软件的关键工具,为开发者们提供了解决问题的智慧和指导。

🚀一、桥接模式(Bridge Pattern)

桥接模式是一种结构型设计模式,它旨在将一个抽象部分与其实现部分分离开来,从而使它们可以独立地变化。这种分离允许我们能够更灵活地应对系统中的变化,并通过面向对象的方法来实现这一目标,而无需引入额外的复杂性。

桥接模式的核心思想是将抽象和实现解耦,这样抽象部分和实现部分可以分别进行变化,而不会相互影响。这使得我们能够在多个方向上扩展和改进系统,而无需担心潜在的混乱和复杂性增加。

桥接模式的主要目的是通过分离抽象和实现,提供一种更加灵活和可维护的设计方式,以适应变化和扩展,同时保持系统的简洁和可理解性。这使得我们可以更容易地构建出适应性强、可扩展的软件系统。

🚀二、使用步骤

🔎1.角色

🦋1.1 抽象(Abstraction)

桥接模式(Bridge Pattern)中的抽象(Abstraction)是一个关键概念,它在设计中扮演着重要的角色。抽象代表了客户端和实现部分的分离点,它具有以下作用:

  1. 分离抽象和实现:抽象在桥接模式中的主要作用是将抽象部分和实现部分分离开来。这意味着抽象定义了一个独立的接口或抽象类,客户端只与抽象进行交互,而不直接与实现部分交互。这种分离允许抽象部分和实现部分可以独立地变化,互不影响。

  2. 提供高层接口:抽象为客户端提供了高层次的接口,这个接口通常包含了客户端感兴趣的操作。客户端可以通过抽象来访问这些操作,而不需要关心具体的实现细节。

  3. 支持多态性:抽象使得客户端可以使用不同的具体实现来替换抽象的实例,从而支持多态性。这意味着客户端可以在运行时选择不同的实现,而不会改变其行为。

  4. 适应变化:由于抽象部分和实现部分分离,当系统中抽象或实现需要变化时,只需修改对应的部分而不会影响另一部分。这提高了系统的灵活性和可维护性。

抽象在桥接模式中的作用是实现抽象部分和实现部分的分离,提供高层接口供客户端使用,支持多态性,同时使得系统更加适应变化。通过抽象,可以构建出具有弹性和可扩展性的系统,同时保持代码的清晰和可维护性。

🦋1.2 扩充抽象(Refined Abstraction)

桥接模式(Bridge Pattern)中的扩充抽象(Refined Abstraction)是一个用于扩展抽象部分的概念,它在桥接模式中起到了重要的作用。扩充抽象允许在已有的抽象接口之上进一步添加或修改方法,以满足具体业务需求,其主要作用包括:

  1. 添加新功能:扩充抽象允许在抽象接口中添加新的方法或属性,从而为客户端提供新的功能。这样可以在不改变现有代码的情况下引入新的功能。

  2. 修改现有行为:如果需要修改抽象接口中的某些方法的行为,可以通过扩充抽象来实现这种修改,而不会影响到其他部分的代码。这有助于在不破坏现有功能的前提下进行修改。

  3. 适应变化:扩充抽象使得系统更加灵活,能够适应业务需求的变化。当新的需求出现时,可以通过扩充抽象来满足这些需求,而不需要修改已有的抽象部分和实现部分。

  4. 保持一致性:扩充抽象可以确保不同的具体实现都具有相同的扩展接口,从而保持了一致性。这意味着客户端可以以相同的方式使用不同的具体实现。

  5. 支持多态性:扩充抽象通过提供新的方法或属性,可以进一步扩展多态性的使用。客户端可以通过抽象接口调用新添加的方法,而不需要关心具体实现。

扩充抽象在桥接模式中的作用是为抽象部分添加新的功能或修改现有功能,以满足业务需求,并保持系统的一致性和可扩展性。这有助于构建出适应变化的系统,同时保持代码的清晰结构和可维护性。

🦋1.3 实现(Implementor)

桥接模式(Bridge Pattern)中的实现(Implementor)是一个关键概念,它在整个模式中扮演着重要的角色。实现代表了抽象部分的具体实现方式,其主要作用包括:

  1. 封装实现细节:实现将抽象部分与其具体的实现细节分离开来,将这些细节封装在具体的实现类中。这有助于隐藏实现的复杂性,使客户端只需要关心抽象接口。

  2. 定义实现接口:实现类定义了抽象部分的实际接口,包括方法和属性。这些接口是抽象部分的具体实现,可以有多个不同的实现类,每个类提供不同的实现方式。

  3. 支持多态性:实现允许客户端在运行时选择不同的实现类,从而实现多态性。客户端可以根据需要切换不同的实现,而不会改变其行为。

  4. 适应变化:由于实现和抽象部分分离,当需要修改或扩展抽象部分的实现时,只需创建新的实现类或修改现有的实现类,而不会影响到抽象部分和其他实现部分。

  5. 提供灵活性:实现允许系统以不同的方式实现相同的抽象接口,这提供了灵活性和可扩展性。不同的实现可以适应不同的业务需求。

实现在桥接模式中的作用是将抽象部分与其具体的实现分离,封装实现细节,定义实现接口,支持多态性,适应变化,以及提供灵活性。这有助于构建出能够适应变化和扩展的系统,同时保持代码的清晰结构和可维护性。实现部分的设计是桥接模式的关键之一,它使得系统更具弹性。

🦋1.4 具体实现(ConcreteImplementor)

桥接模式(Bridge Pattern)中的具体实现(Concrete Implementor)是实现抽象部分的具体类,它用于实际定义抽象部分的实现方式,其主要作用包括:

  1. 实现抽象接口:具体实现类必须实现抽象实现(Implementor)定义的接口或抽象类中的方法和属性。这些方法和属性定义了抽象部分的实际功能和行为。

  2. 提供具体的实现细节:具体实现类负责提供抽象部分的具体实现细节。这些细节可能包括底层数据结构、算法、操作等。

  3. 支持多态性:具体实现类可以有多个不同的实现,它们都实现了相同的抽象接口。这使得客户端可以在运行时选择不同的具体实现,从而实现多态性。

  4. 适应变化:由于具体实现类与抽象部分分离,当需要修改或扩展抽象部分的实现时,只需创建新的具体实现类或修改现有的具体实现类,而不会影响到抽象部分和其他具体实现部分。

  5. 灵活性:具体实现类的设计允许系统以不同的方式实现相同的抽象接口,这提供了灵活性和可扩展性。不同的具体实现可以满足不同的业务需求。

具体实现在桥接模式中的作用是将抽象部分的概念映射到具体的实际实现细节,实现抽象接口,提供具体的实现功能,支持多态性,适应变化,并提供灵活性。具体实现类的设计是桥接模式中的关键之一,它使得系统更具弹性,能够适应不同的需求和变化。

🔎2.示例

在这里插入图片描述

命名空间BridgePattern中包含电视机基类,3个具体电视机类,一个遥控器基类和1个具体遥控器类。本案例尝试使用桥接模式来解决如何用遥控器来遥控不同的电视机完成相应的动作。

public abstract class Television {

    public abstract void TurnOn();

    public abstract void TurnOff();

    public abstract void TurnChannel();

}

电视机基Television类,包含打开电视TurnOn、关闭电视TurnOff、换台功能TurnChannel。

public class Konka : Television {

    public override void TurnOn() {
        Console.WriteLine("Turn on Konka!");
    }

    public override void TurnOff() {
        Console.WriteLine("Turn off Konka!");
    }

    public override void TurnChannel() {
        Console.WriteLine("Turn channel Konka!");
    }

}

具体电视类,康佳Konka类。

public class Lenovo : Television {

    public override void TurnOn() {
        Console.WriteLine("Turn on Lenovo!");
    }

    public override void TurnOff() {
        Console.WriteLine("Turn off Lenovo!");
    }

    public override void TurnChannel() {
        Console.WriteLine("Turn channel Lenovo!");
    }

}

具体电视类,联想Lenovo类。

public class Panasonic : Television {

    public override void TurnOn() {
        Console.WriteLine("Turn on Panasonic!");
    }

    public override void TurnOff() {
        Console.WriteLine("Turn off Panasonic!");
    }

    public override void TurnChannel() {
        Console.WriteLine("Turn channel Panasonic!");
    }

}

具体电视类,松下Panasonic类。

public class TeleControllerBase {

    public Television Television { get; set; }

    public virtual void TurnOn() {
        Television.TurnOn();
    }

    public virtual void TurnOff() {
        Television.TurnOff();
    }

    public virtual void TurnChannel() {
        Television.TurnChannel();
    }

}

遥控器基类TeleControllerBase类,内部维持一个电视机基类的引用,并包含对应的3个电视机功能。

public class TeleController : TeleControllerBase {

    public override void TurnOff() {
        base.TurnOff();
        Console.WriteLine("-------------------------");
    }

}

具体遥控器TeleController类。

public class Program {

    private static TeleControllerBase _teleController = null;

    public static void Main(string[] args) {
        _teleController = new TeleController();

        _teleController.Television = new Konka();
        _teleController.TurnOn();
        _teleController.TurnChannel();
        _teleController.TurnOff();

        _teleController.Television = new Lenovo();
        _teleController.TurnOn();
        _teleController.TurnChannel();
        _teleController.TurnOff();

        _teleController.Television = new Panasonic();
        _teleController.TurnOn();
        _teleController.TurnChannel();
        _teleController.TurnOff();

        Console.ReadKey();
    }

}

以上是调用方的代码,以下是这个案例的输出结果:

Turn on Konka!
Turn channel Konka!
Turn off Konka!
-------------------------
Turn on Lenovo!
Turn channel Lenovo!
Turn off Lenovo!
-------------------------
Turn on Panasonic!
Turn channel Panasonic!
Turn off Panasonic!
-------------------------

🚀总结

🔎1.优点

桥接模式(Bridge Pattern)是一种常用的设计模式,它具有许多优点,可以改善软件系统的设计和结构,其中一些主要的优点包括:

  1. 分离抽象与实现:桥接模式将抽象部分和实现部分分离开来,使得它们可以独立地变化。这种分离提高了系统的灵活性,允许它们分别进行扩展和修改,而不会影响到对方。

  2. 提高可扩展性:由于抽象部分和实现部分分离,系统可以轻松地引入新的抽象部分或实现部分,从而增加了可扩展性。这有助于适应未来的需求变化。

  3. 支持多态性:桥接模式支持多态性,允许客户端在运行时选择不同的抽象和实现的组合,以满足不同的需求,同时保持接口一致性。

  4. 简化代码:通过将复杂的继承关系替换为对象组合,桥接模式可以简化类的层次结构,减少了类的数量,使代码更加清晰和易于理解。

  5. 改善可维护性:分离抽象和实现使得系统更容易维护。当需要修改抽象或实现时,只需修改相应的类,而不会影响到其他部分。

  6. 促进代码复用:通过将不同的抽象部分与相同的实现部分组合,桥接模式促进了代码的复用,避免了重复编写相似的代码。

  7. 提高系统的健壮性:由于桥接模式允许分离不同的部分,因此系统更加稳定,一个部分的问题不会波及到其他部分。

桥接模式的优点包括分离抽象和实现、提高可扩展性、支持多态性、简化代码、改善可维护性、促进代码复用和提高系统的健壮性。这些优点使得桥接模式在面对复杂的系统设计和需求变化时非常有用,有助于构建出灵活、可维护和可扩展的软件系统。

🔎2.缺点

桥接模式(Bridge Pattern)在许多情况下都是一种有用的设计模式,但它也有一些缺点和限制,需要考虑:

  1. 增加复杂性:桥接模式引入了额外的抽象层次和对象组合,这可能增加代码的复杂性。在简单的情况下,使用桥接模式可能显得过于繁琐。

  2. 抽象与实现的匹配:桥接模式要求抽象部分和实现部分必须一一对应,这可能导致在设计时需要额外的考虑和匹配工作。如果不恰当地匹配抽象和实现,可能会导致设计错误。

  3. 增加类的数量:使用桥接模式可能导致创建多个抽象和实现的子类,这可能会增加类的数量。如果不管理好类的数量,可能会导致系统复杂度的增加。

  4. 不适合小规模应用:对于小规模、简单的应用程序,引入桥接模式可能会显得过于繁重,增加了开发和维护的成本。

  5. 可能引入性能开销:由于桥接模式引入了额外的抽象层次和对象组合,可能会引入一定的性能开销。在对性能要求非常高的应用中,需要谨慎使用。

  6. 设计难度:正确设计桥接模式可能需要一定的经验和设计能力,特别是在复杂系统中。不恰当的设计可能会导致混乱和不必要的复杂性。

桥接模式虽然有许多优点,但也存在一些缺点和限制,需要在具体情况下仔细权衡。通常情况下,桥接模式更适用于复杂的系统或需要支持多态性和可扩展性的情况,而在简单的情况下可能不是最佳选择。设计师应该根据具体需求和项目规模来决定是否采用桥接模式。

🔎3.使用场景

桥接模式(Bridge Pattern)适用于以下一些常见场景和情况:

  1. 抽象与实现分离:当需要将抽象部分和实现部分分离开来,以便它们可以独立地变化和扩展时,桥接模式非常有用。这种分离可以帮助应对系统中抽象和实现的不断变化。

  2. 多态性需求:当希望客户端能够在运行时选择不同的抽象和实现的组合,以实现多态性,桥接模式是一个有效的选择。它允许客户端灵活地替换抽象或实现部分,而不会改变整体的接口。

  3. 复杂的类层次结构:在存在复杂的类层次结构时,使用继承来管理抽象和实现可能会导致类爆炸的问题。桥接模式可以帮助简化类层次结构,减少继承关系,提高代码的可维护性。

  4. 不同平台或数据库的支持:在跨多个平台或数据库进行开发时,桥接模式可以用于将通用功能与特定平台或数据库的实现分离开来。这有助于在不同环境下重用通用代码。

  5. 图形界面库:桥接模式常用于图形界面库,其中抽象部分通常表示控件(如按钮、文本框),而实现部分表示不同操作系统或图形库中的具体实现。这使得跨多个平台的图形界面开发更容易。

  6. 电子设备和遥控器:在控制电子设备(如电视、音响)的遥控器设计中,桥接模式可以用于将不同类型的电子设备与不同类型的遥控器分离开来,以实现灵活的组合。

  7. 框架和工具库:在开发通用框架或工具库时,桥接模式可以用于将核心功能与具体实现分离,以允许不同应用程序使用不同的具体实现。

桥接模式在需要分离抽象和实现、支持多态性、简化复杂类层次结构以及跨平台或数据库的开发等情况下非常有用。它提供了一种灵活的设计方式,有助于构建可维护、可扩展和可复用的软件系统。但在小规模、简单的应用中,可能不需要引入桥接模


🚀感谢:给读者的一封信

亲爱的读者,

我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。

如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。

我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。

如果您愿意支持我的创作,请扫描下面二维码,您的支持将不胜感激。同时,如果您有任何反馈或建议,也欢迎与我分享。

在这里插入图片描述

再次感谢您的阅读和支持!

最诚挚的问候, “愚公搬代码”

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。