多维度思考——桥接模式

桥接模式

​ Bridge Pattern:桥接模式,是GoF23种设计模式中属于结构型模式的一种。

​ 桥接模式通过在抽象和具体实现之间创建桥接的结构用以实现两者的解耦合。抽象部分和实现部分是完全分离的,两者都可以独自变化而不影响对方。

​ 桥接模式的关注点在于抽象和实现两者之间的关系,并不是传统上所体现的抽象类和他的派生类这样的的关系(或者说是父类和子类这样的关系,而是说是一种抽象类具体的表达形式),也就是说 实现 指的就是抽象类和派生类用来实现自己的对象,再换句话说就是 实现的方法方式或者角度有多种,每一种都有自己的变化,而我们就是需要将这种多角度多方式分离出来,让它们独立变化,达到减少它们之间耦合的目的。

​ 举个例子说,对于同一个形状。比如说是圆,对其进行分类的话,我们可以通过半径的大小分类,同时我们也可以按照颜色分类,或者按照圆的边缘不同线(点线啊,实线啊,虚线啊等等)分类。

​ 这个例子中,形状就是抽象,圆就是派生类。4CM的圆或者红色的圆,或者虚线绘制的圆就是具体的实现方式,抽象和实现两者都可以独立更改,两者是解耦合的。

结构

桥接模式类图
​ 结合类图分析,桥接模式分割明确,总共有两大阵营:

  • 作为抽象化角色和实际对象(也叫做修正抽象化角色)组成的抽象阵营。
    • 抽象化角色:给出的抽象化定义,同时保存一个对实现化角色对象的引用。
    • 实际对象(修正抽象化角色):扩展了抽象角色的实际对象,改变抽象化角色对于抽象化的定义。
  • 作为实现化角色和具体实现化角色组成的实现阵营。
    • 实现化角色:只给出实现化的接口。
    • 具体实现角色:给出实现化角色接口的具体实现。

有点不好理解,额~~~

对于桥接模式来说解决的是一个多角度的问题,多方向的问题,多维度的问题,让它们独立出来,考虑的时候只考虑某一个维度/角度/方向,最后才组合在一起形成最后的具体所需要的对象。

举例
  • 常用的例子是绘制图形。比如说想要绘制一个正方形,三角形,圆,那么我们应该有三个对应的解决方案。但是很快新的需求来了,我们需要加颜色,红色,白色,黑色。

    也就是这个时候,对于同一个抽象的形状他是有两个维度的变化的,一是具体的形状,二是具体的颜色。

    那么如果我们可以将这两个维度分开考虑,最后组合在一起,这样是不是复杂的下降了呢?

    这也就是桥接模式的作用,可以让我们不需要定义红色的正方形,红色的三角形,红色的圆或者白色的正方形,白色的三角形,白色的圆这种复杂的形式。而是,直接,正方形,红色,之后组合成为红色的正方形,这样是不是变得简单了些?

注意
  1. 桥接模式适用与描绘多维度变化的系统,通过该模式和面向对象技术来使得系统能够轻松的沿着多个方向进行变化但是又不增加额外的复杂度。
  2. 桥接模式使用的要求较高,会怎加理解和设计的难度。
  3. 抽象和实现的分离使得代码低耦合,同时扩展能力也很优秀。
一个小DEMO
  1. 场景

    就以举例中的小例子为例

  2. 实现化角色

    /**
     * 桥接模式 —— 实现化角色
     * @author wq
     */
    public interface Implementor {
    	void doSomething();
    }
    
  3. 维度一:颜色

    /**
     * 桥接模式 —— 具体实现化角色
     * @author wq
     */
    public class Red implements Implementor{
    
    	@Override
    	public void doSomething() {
    		System.out.println("红色");
    	}
    
    }
    //----------------------------------------------------
    /**
     * 桥接模式 —— 具体实现化角色
     * @author wq
     */
    public class Blue implements Implementor{
    
    	@Override
    	public void doSomething() {
    		System.out.println("蓝色");
    	}
    
    }
    
  4. 抽象化角色

    /**
     * 桥接模式 —— 抽象化角色
     * @author wq
     */
    public abstract class Abstraction {
    	// 保存着一个实现化角色的对象 这是组合/聚合原则的使用
    	protected Implementor implementor;
    	
    	public Abstraction(Implementor implementor) {
    		this.implementor = implementor;
    	}
    	
    	public abstract void doSomething();
    }
    
  5. 维度二:形状

    /**
     * 桥接模式 —— 修正抽象化角色
     * @author wq
     */
    public class Circle extends Abstraction{
    
    	public Circle(Implementor implementor) {
    		super(implementor);
    	}
    
    	@Override
    	public void doSomething() {
    		System.out.println("修正抽象化角色 ---- 我是一个圆");
    		System.out.print("实现化角色 ---- ");
    		implementor.doSomething();
    	}
    }
    //-------------------------------------------------------------
    /**
     * 桥接模式 —— 修正抽象化角色
     * @author wq
     */
    public class Triangle extends Abstraction{
    
    	public Triangle(Implementor implementor) {
    		super(implementor);
    	}
    
    	@Override
    	public void doSomething() {
    		System.out.println("修正抽象化角色 ---- 我是一个三角形");
    		System.out.print("实现化角色 ---- ");
    		implementor.doSomething();
    	}
    }
    
  6. 测试类

    /**
     * 桥接模式 —— 测试类
     * @author wq
     */
    public class Main {
    	public static void main(String[] args) {
    		Abstraction circle = new Circle(new Red());
    		Abstraction triangle = new Triangle(new Blue());
    		
    		circle.doSomething();
    		System.out.println("------------------------------");
    		triangle.doSomething();
    	}
    }
    
  7. 测试走一波

    修正抽象化角色 ---- 我是一个圆
    实现化角色 ---- 红色
    ------------------------------
    修正抽象化角色 ---- 我是一个三角形
    实现化角色 ---- 蓝色
    

完成!!!

桥接模式是一种结构型设计模式,它将抽象和实现分离,使它们可以独立地变化。桥接模式的核心思想是将一个大类或一组类分解成抽象和实现两个独立的维度,使它们可以独立地变化和扩展,同时通过桥接来将它们连接起来。 在C++中,桥接模式通常通过虚函数实现。抽象部分通过基类定义接口,而实现部分通过派生类实现具体的功能。通过将抽象部分的指针作为参数传递给实现部分的函数,就可以实现两个部分的连接。 下面是一个简单的桥接模式的C++示例: ```c++ class Implementor { public: virtual void operation() = 0; virtual ~Implementor() {} }; class ConcreteImplementorA : public Implementor { public: void operation() override { // 具体的实现A } }; class ConcreteImplementorB : public Implementor { public: void operation() override { // 具体的实现B } }; class Abstraction { public: Abstraction(Implementor* implementor) : m_implementor(implementor) {} virtual void operation() = 0; virtual ~Abstraction() {} protected: Implementor* m_implementor; }; class RefinedAbstraction : public Abstraction { public: RefinedAbstraction(Implementor* implementor) : Abstraction(implementor) {} void operation() override { m_implementor->operation(); // 其他操作 } }; int main() { Implementor* implementorA = new ConcreteImplementorA(); Implementor* implementorB = new ConcreteImplementorB(); Abstraction* abstractionA = new RefinedAbstraction(implementorA); Abstraction* abstractionB = new RefinedAbstraction(implementorB); abstractionA->operation(); abstractionB->operation(); delete abstractionA; delete abstractionB; delete implementorA; delete implementorB; return 0; } ``` 在上面的示例中,Implementor是实现部分的抽象基类,ConcreteImplementorA和ConcreteImplementorB是具体的实现类。Abstraction是抽象部分的基类,RefinedAbstraction是抽象部分的具体实现类。在main函数中,我们创建了不同的Implementor和Abstraction对象,并通过它们来完成不同的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值