赞
踩
本文主要的思路和代码,来自于对以下连接的学习和实现:
桥接模式,顾名思义,就像是一座连接两岸的桥梁。在软件开发中,我们可以将桥接模式看作是一座连接抽象部分和实现部分的“桥”,通过这座“桥”,我们可以方便地在抽象部分和实现部分之间进行切换,而不需要关心它们之间的实现细节。
桥接模式的核心作用就是降低系统的耦合度,提高扩展性和可维护性。想象一下你正在修建一座连接两个城市的大桥,如果没有这座桥,你需要绕行很远的距离才能到达对岸。同样地,在软件开发中,如果没有桥接模式,抽象部分和实现部分之间的依赖关系可能会变得非常复杂,导致系统难以扩展和维护。
桥接模式和其他设计模式都是非常有用的工具,它们可以帮助我们更好地组织和管理代码,提高系统的可维护性和可扩展性。在使用这些工具时,我们需要根据具体的需求和场景来选择合适的模式,以最大程度地发挥它们的效用。
桥接模式的应用场景也非常广泛。比如我们正在开发一个电商网站,其中有一个订单管理系统和一个支付系统。这两个系统分别负责订单的处理和支付的操作,但是它们之间的关系非常紧密。如果没有桥接模式,我们需要在订单管理系统和支付系统中都实现相同的逻辑,这显然是不合理的。而如果我们使用桥接模式,可以将订单管理系统和支付系统分别抽象成两个独立的类,并通过一个桥接器来协调它们之间的交互,这样就可以避免代码冗余和耦合度过高的问题。如果我们概括一下桥接模式的使用场景的话,主要有以下几个:
桥接模式的实现方式就像是一座连接不同平台的桥梁,它通过抽象部分和实现部分之间的关联来实现。如果以连接桥梁为例,其大致的步骤为:
抽象部分在桥接模式中起到了至关重要的连接作用。它通过定义接口、封装逻辑、委派工作等方式,将不同的平台进行连接,并帮助客户端与实现部分进行交互。
抽象部分就像是一座桥梁的桥墩,它具体负责了下面的一些内容:
具体部分在桥接模式中同样起到了至关重要的作用。它通过实现抽象部分所定义的方法和属性,完成具体的操作,并帮助客户端与实现部分进行交互。同时,具体部分还可以根据抽象部分的定义,使用不同的实现方式来完成不同的业务逻辑。
具体部分就像是一座桥梁的桥面和支撑结构,它具体负责了下面的一些内容:
综上所述,桥接模式的优点在于它可以帮助我们更好地组织和管理代码,提高系统的可维护性和可扩展性。通过创建与平台无关的类和程序、客户端代码仅与高层抽象部分进行互动、遵循开闭原则以及单一职责原则等特性,桥接模式为我们提供了一个灵活、高效且易于维护的设计方案。
综上所述,桥接模式是一种灵活的设计模式,可以帮助我们更好地组织和管理代码。然而,在使用该模式时也需要注意一些潜在的问题和挑战。就像建造一座桥梁需要考虑许多因素一样,使用桥接模式也需要综合考虑各种因素,以确保系统的正确性和可靠性。
// “抽象部分”定义了两个类层次结构中“控制”部分的接口。它管理着一个指向“实 // 现部分”层次结构中对象的引用,并会将所有真实工作委派给该对象。 class RemoteControl is protected field device: Device constructor RemoteControl(device: Device) is this.device = device method togglePower() is if (device.isEnabled()) then device.disable() else device.enable() method volumeDown() is device.setVolume(device.getVolume() - 10) method volumeUp() is device.setVolume(device.getVolume() + 10) method channelDown() is device.setChannel(device.getChannel() - 1) method channelUp() is device.setChannel(device.getChannel() + 1) // 你可以独立于设备类的方式从抽象层中扩展类。 class AdvancedRemoteControl extends RemoteControl is method mute() is device.setVolume(0) // “实现部分”接口声明了在所有具体实现类中通用的方法。它不需要与抽象接口相 // 匹配。实际上,这两个接口可以完全不一样。通常实现接口只提供原语操作,而 // 抽象接口则会基于这些操作定义较高层次的操作。 interface Device is method isEnabled() method enable() method disable() method getVolume() method setVolume(percent) method getChannel() method setChannel(channel) // 所有设备都遵循相同的接口。 class Tv implements Device is // …… class Radio implements Device is // …… // 客户端代码中的某个位置。 tv = new Tv() remote = new RemoteControl(tv) remote.togglePower() radio = new Radio() remote = new AdvancedRemoteControl(radio)
#include <iostream> #include <string> /** * The Implementation defines the interface for all implementation classes. It * doesn't have to match the Abstraction's interface. In fact, the two * interfaces can be entirely different. Typically the Implementation interface * provides only primitive operations, while the Abstraction defines higher- * level operations based on those primitives. */ class Implementation { public: virtual ~Implementation() {} virtual std::string OperationImplementation() const = 0; }; /** * Each Concrete Implementation corresponds to a specific platform and * implements the Implementation interface using that platform's API. */ class ConcreteImplementationA : public Implementation { public: std::string OperationImplementation() const override { return "ConcreteImplementationA: Here's the result on the platform A.\n"; } }; class ConcreteImplementationB : public Implementation { public: std::string OperationImplementation() const override { return "ConcreteImplementationB: Here's the result on the platform B.\n"; } }; /** * The Abstraction defines the interface for the "control" part of the two class * hierarchies. It maintains a reference to an object of the Implementation * hierarchy and delegates all of the real work to this object. */ class Abstraction { /** * @var Implementation */ protected: Implementation *implementation_; public: Abstraction(Implementation *implementation) : implementation_(implementation) { } virtual ~Abstraction() { } virtual std::string Operation() const { return "Abstraction: Base operation with:\n" + this->implementation_->OperationImplementation(); } }; /** * You can extend the Abstraction without changing the Implementation classes. */ class ExtendedAbstraction : public Abstraction { public: ExtendedAbstraction(Implementation *implementation) : Abstraction(implementation) { } std::string Operation() const override { return "ExtendedAbstraction: Extended operation with:\n" + this->implementation_->OperationImplementation(); } }; /** * Except for the initialization phase, where an Abstraction object gets linked * with a specific Implementation object, the client code should only depend on * the Abstraction class. This way the client code can support any abstraction- * implementation combination. */ void ClientCode(const Abstraction &abstraction) { // ... std::cout << abstraction.Operation(); // ... } /** * The client code should be able to work with any pre-configured abstraction- * implementation combination. */ void BridgeExample() { Implementation *implementation = new ConcreteImplementationA; Abstraction *abstraction = new Abstraction(implementation); ClientCode(*abstraction); std::cout << std::endl; delete implementation; delete abstraction; implementation = new ConcreteImplementationB; abstraction = new ExtendedAbstraction(implementation); ClientCode(*abstraction); delete implementation; delete abstraction; }
#ifndef _REMOTE_EXAMPLE_H_ #define _REMOTE_EXAMPLE_H_ // The abstract Device class. class Device { public: virtual bool isEnabled() = 0; virtual void enable() = 0; virtual void disable() = 0; virtual int getVolume() = 0; virtual void setVolume(int volume) = 0; virtual int getChannel() = 0; virtual void setChannel(int channel) = 0; protected: virtual bool checkIsValidVolume(int volume) const = 0; virtual bool checkIsValidChannel(int channel) const = 0; }; class RemoteControl { protected: Device* m_pDevice = nullptr; public: RemoteControl(Device* pDevice); void togglePower(); void volumeDown(); void volumeUp(); void channelDown(); void channelUp(); }; class AdvancedRemoteControl : public RemoteControl { public: void mute(); }; class TVDevice : public Device { public: TVDevice(bool isEnabled = false, int volume = 1, int channel = 0); bool isEnabled() override; void enable() override; void disable() override; int getVolume() override; void setVolume(int volume) override; int getChannel() override; void setChannel(int channel) override; void printDeviceInfo(); private: bool checkIsValidVolume(int volume) const override; bool checkIsValidChannel(int channel) const override; private: bool m_isEnabled = false; int m_volume = 1; int m_channel = 0; }; class RadioDevice : public Device { public: RadioDevice(bool isEnabled = false, int volume = 1, int channel = 0); bool isEnabled() override; void enable() override; void disable() override; int getVolume() override; void setVolume(int volume) override; int getChannel() override; void setChannel(int channel) override; void printDeviceInfo(); private: bool checkIsValidVolume(int volume) const override; bool checkIsValidChannel(int channel) const override; private: bool m_isEnabled = false; int m_volume = 1; int m_channel = 0; }; class RemoteExample { public: static void TVControlCase(); static void RadioControlCase(); }; #endif // _REMOTE_EXAMPLE_H_
#include "remote_example.h" #include <iostream> namespace { constexpr int TV_VOLUME_MAX = 100; constexpr int TV_CHANNEL_MAX = 256; constexpr int RADIO_VOLUME_MAX = 200; constexpr int RADIO_CHANNEL_MAX = 512; } RemoteControl::RemoteControl(Device* pDevice) : m_pDevice(pDevice) { } void RemoteControl::togglePower() { if (m_pDevice->isEnabled()) { m_pDevice->disable(); } else { m_pDevice->enable(); } } void RemoteControl::volumeDown() { m_pDevice->setVolume(m_pDevice->getVolume() - 10); } void RemoteControl::volumeUp() { m_pDevice->setVolume(m_pDevice->getVolume() + 10); } void RemoteControl::channelDown() { m_pDevice->setChannel(m_pDevice->getChannel() - 1); } void RemoteControl::channelUp() { m_pDevice->setChannel(m_pDevice->getChannel() + 1); } void AdvancedRemoteControl::mute() { m_pDevice->setVolume(0); } TVDevice::TVDevice(bool isEnabled /*= true*/, int volume /*= 1*/, int channel /*= 0*/) : m_isEnabled(isEnabled) , m_volume(volume) , m_channel(channel) { } bool TVDevice::isEnabled() { return m_isEnabled; } void TVDevice::enable() { m_isEnabled = true; } void TVDevice::disable() { m_isEnabled = false; } int TVDevice::getVolume() { return m_volume; } void TVDevice::setVolume(int volume) { if (checkIsValidVolume(volume)) { m_volume = volume; } else { std::cout << "Error volume for this TV Device!" << std::endl; } } int TVDevice::getChannel() { return m_channel; } void TVDevice::setChannel(int channel) { if (checkIsValidChannel(channel)) { m_channel = channel; } else { std::cout << "Error channel for this TV Device!" << std::endl; } } void TVDevice::printDeviceInfo() { std::cout << "TVDevice Info : Volume :" << m_volume << '\t' << "Channel : " << m_channel << std::endl; } bool TVDevice::checkIsValidVolume(int volume) const { return (volume >= 0 && volume <= TV_VOLUME_MAX) ? true : false; } bool TVDevice::checkIsValidChannel(int channel) const { return (channel >= 0 && channel <= TV_CHANNEL_MAX) ? true : false; } RadioDevice::RadioDevice(bool isEnabled /*= true*/, int volume /*= 1*/, int channel /*= 0*/) : m_isEnabled(isEnabled) , m_volume(volume) , m_channel(channel) { } bool RadioDevice::isEnabled() { return m_isEnabled; } void RadioDevice::enable() { m_isEnabled = true; } void RadioDevice::disable() { m_isEnabled = false; } int RadioDevice::getVolume() { return m_volume; } void RadioDevice::setVolume(int volume) { if (checkIsValidVolume(volume)) { m_volume = volume; } else { std::cout << "Error volume for this TV Device!" << std::endl; } } int RadioDevice::getChannel() { return m_channel; } void RadioDevice::setChannel(int channel) { if (checkIsValidChannel(channel)) { m_channel = channel; } else { std::cout << "Error channel for this TV Device!" << std::endl; } } bool RadioDevice::checkIsValidVolume(int volume) const { return (volume >= 0 && volume <= RADIO_VOLUME_MAX) ? true : false; } bool RadioDevice::checkIsValidChannel(int channel) const { return (channel >= 0 && channel <= RADIO_CHANNEL_MAX) ? true : false; } void RadioDevice::printDeviceInfo() { std::cout << "RadioDevice Info : Volume :" << m_volume << '\t' << "Channel : " << m_channel << std::endl; } void RemoteExample::TVControlCase() { std::cout << "\nTV Device example case start." << std::endl; TVDevice tv; RemoteControl remoteTv(&tv); remoteTv.togglePower(); tv.printDeviceInfo(); remoteTv.channelUp(); std::cout << "After TV channel up:" << std::endl; tv.printDeviceInfo(); remoteTv.volumeUp(); std::cout << "After TV volume Up:" << std::endl; tv.printDeviceInfo(); AdvancedRemoteControl adRemote(&tv); adRemote.mute(); std::cout << "After TV is muted:" << std::endl; tv.printDeviceInfo(); std::cout << "\nTV Device example case end." << std::endl; } void RemoteExample::RadioControlCase() { std::cout << "\nRadio Device example case start." << std::endl; RadioDevice radio; RemoteControl remoteRadio(&radio); remoteRadio.togglePower(); radio.printDeviceInfo(); remoteRadio.channelUp(); std::cout << "After Radio channel up:" << std::endl; radio.printDeviceInfo(); remoteRadio.volumeUp(); std::cout << "After Radio volume Up:" << std::endl; radio.printDeviceInfo(); AdvancedRemoteControl adRemote(&radio); adRemote.mute(); std::cout << "After Radio is muted:" << std::endl; radio.printDeviceInfo(); std::cout << "\nRadio Device example case end." << std::endl; }
相关代码由以下类组成:
Implementation
:这是一个抽象基类,定义了所有实现类的接口。它有一个纯虚函数 OperationImplementation()
。
ConcreteImplementationA
和 ConcreteImplementationB
:这两个类是 Implementation
的具体实现,分别对应平台A和平台B。它们实现了 OperationImplementation()
方法,返回特定平台的结果。
Abstraction
:这个类定义了控制部分的接口,并维护了一个对 Implementation
类的对象的引用。它有一个虚函数 Operation()
,该函数通过委托给 implementation_
对象来执行实际工作。
ExtendedAbstraction
:这是 Abstraction
的子类,扩展了其功能。它在 Operation()
中添加了一些额外的操作。
ClientCode
和 BridgeExample
:这两个函数/方法用于客户端代码,与抽象和实现类进行交互。
这些类的角色如下:
Implementation
:定义了所有实现类的接口。ConcreteImplementationA
和 ConcreteImplementationB
:实现了 Implementation
接口,提供了特定平台的实现。Abstraction
:作为控制部分的接口,封装了对 Implementation
对象的引用,并提供了基本的操作。ExtendedAbstraction
:扩展了 Abstraction
的功能。ClientCode
和 BridgeExample
:客户端代码,与抽象和实现类进行交互。模式中的各个元素以以下方式相互关联:
Abstraction
类包含一个指向 Implementation
类的指针,并通过该指针调用 OperationImplementation()
方法。ExtendedAbstraction
类继承自 Abstraction
类,并重写了 Operation()
方法,增加了额外的操作。ClientCode
函数接受一个 Abstraction
类的引用,并通过该引用调用 Operation()
方法。BridgeExample
函数演示了如何使用不同的 Abstraction
和 Implementation
组合创建对象,并通过 ClientCode
函数调用相应的操作。相关代码由以下类组成:
Device
:这是一个抽象类,定义了一些设备共有的属性和方法,如检查设备是否启用、获取和设置音量和频道等。
RemoteControl
:这是一个基类,它有一个指向Device
类的指针,并定义了一些远程控制设备的基本操作,如切换电源、调整音量和频道等。
AdvancedRemoteControl
:这是RemoteControl
的子类,增加了静音功能。
TVDevice
和 RadioDevice
:这两个类都继承自Device
类,分别代表电视设备和无线电设备。它们都实现了Device
类中的虚函数,并添加了一些特定于设备的属性和方法,如打印设备信息等。
RemoteExample
:这是一个包含两个静态方法的类,用于在其他地方调用以执行特定的远程控制案例。
这些类的角色如下:
Device
:作为所有设备的基类,定义了通用的设备属性和方法。RemoteControl
:作为远程控制的基类,提供了一些设备的基本操作。AdvancedRemoteControl
:扩展了远程控制的功能,包括静音。TVDevice
和 RadioDevice
:这两个类代表了具体的设备类型,它们继承了Device
类,并实现了Device
类中的方法,添加了特定于设备的属性和方法。RemoteExample
:包含了两个静态方法,用于在其他地方执行特定的远程控制案例。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。