用心理解设计模式——桥接模式 / 桥梁模式 (Bridge Pattern)

前置文章: 设计模式的原则 

其他设计模式:用心理解设计模式

设计模式相关代码已统一放至 我的 Github

一、定义

  结构型模式之一。

  Decouple an abstraction from its implementation so that the two can vary independently.

  (将抽象和实现解耦, 这样两者就可以独立地变化。)

二、结构解析

  桥接模式的一般结构有四种角色: 抽象实现者、具体实现者、抽象物体、精确抽象物体。

  抽象物体(Abstraction):包含一个接口方法(可以多个),并持有一个抽象实现者(可以多个)。这个接口方法有扩展需求,但无法通过继承重写本类的方式扩展(和本类继承扩展的方向不同),所以,就在该方法的实现里原封不动地调用了抽象实现者的抽象接口,并希望通过派生抽象实现者,使这个接口方法得以在另一个维度上扩展。

  抽象实现者(Implementor):定义一个抽象接口,它是抽象物体中要扩展的方法的抽象实现(注意是抽象实现,正因为如此,所以才能扩展出多种不同的具体实现,让实现在一个方向上独立地变化)。

  具体实现者(ConcreateImplementor):继承抽象实现者,实现抽象实现者定义的抽象接口,实际是为抽象物体中要扩展的方法给出具体实现

  精确抽象物体(RefinedAbstraction):首先,它反映了抽象物体通过继承扩展的方向。它为什么要叫做 “精确抽象物体” ,而不是 “具体物体”?因为,虽然它在自身继承扩展的方向上已经变成了具体的,但它包含的 “抽象物体中定义的要扩展的方法” 还没有具体实现,在没和一个具体实现者结合前,这个方法似乎就相当于一个抽象方法,那么这个类也就相当于一个抽象类。所以,它实际上只是从一个完全抽象的类,变成了一个半抽象的类,没有完全具体,所以就叫它 “精确抽象类”。

三、评价

  桥接模式 为拥有 “多重不同修饰(行为) 类的多维扩展” 问题,提供了灵活的、有效的方案。即,先分离抽象类和实现类,然后使各自派生,最后进行自由组合。

  桥接模式的扩展能力是多维度的,这取决于一个抽象物体对应几个抽象实现者,又取决于抽象物体中要扩展的接口方法的数量(一个要扩展的接口方法,对应一个抽象实现者)。

  比如,有一个抽象物体(有两个精确抽象物体子类),它含有两个要扩展的接口方法(对应两个抽象实现者),每个抽象实现者都有三个具体实现,那么组合的可能性为 2*3*3,这是一个三维的扩展(包括:一个类本身抽象的扩展 和 两个抽象实现者的扩展)。如果此时,为抽象物体增加一个要扩展的接口方法,那么组合的可能性就变成了 2*3*3*3。

  桥接模式符合开闭原则,增加扩展维度(增加要扩展的接口方法)很容易。

  可以对比另一个解决  “两重不同修饰”  问题的 抽象工厂模式,抽象工厂模式用于创建对象,通过 “在抽象父类中持有一族方法然后派生子类实现不同方法” 达到了二维扩展的目的。

  桥接模式在有 “多重不同修饰” 的扩展需求时,比使用继承更简洁、更灵活。它通过抽象和实现的组合,避免了通过继承方式扩展,导致出现大量静态类的问题(这个优点 装饰器模式 也有。区别是桥接模式是二维表格式组合,装饰器模式是在一维上进行选择和排列)。

四、实现

using UnityEngine;

namespace Bridge
{ 
    //抽象实现者
    public abstract class Implementor
    {
        public abstract void DoSthImp();
    }

    //具体实现者A
    public class ConcreateImplementorA : Implementor
    {
        public override void DoSthImp()
        {
            Debug.Log("做A事");
        }
    }
    
    //具体实现者B
    public class ConcreateImplementorB : Implementor
    {
        public override void DoSthImp()
        {
            Debug.Log("做B事");
        }
    }

    //抽象物体
    public abstract class Abstraction
    {
        private Implementor implementor;
        public Abstraction(Implementor implementor)
        {
            this.implementor = implementor;
        }

        public void DoSth()
        {
            this.implementor.DoSthImp();
        }
    }

    //精确抽象物体X
    public class RefinedAbstractionX : Abstraction
    {
        public RefinedAbstractionX(Implementor implementor) : base(implementor)
        {
            Debug.Log(" RefinedAbstractionX ");
        }
    }

    //精确抽象物体Y
    public class RefinedAbstractionY : Abstraction
    {
        public RefinedAbstractionY(Implementor implementor) : base(implementor)
        {
            Debug.Log(" RefinedAbstractionY ");
        }
    }

    public class Client
    {
        static public void Main()
        {
            //为精确抽象物体X指定一个实现,以形成一个真实物体。
            //精确抽象物体和实现可以自由组合。
            RefinedAbstractionX rax1 = new RefinedAbstractionX(new ConcreateImplementorA());
            rax1.DoSth();

            RefinedAbstractionX rax2 = new RefinedAbstractionX(new ConcreateImplementorB());
            rax2.DoSth();

            RefinedAbstractionY ray1 = new RefinedAbstractionY(new ConcreateImplementorA());
            ray1.DoSth();

            RefinedAbstractionY ray2 = new RefinedAbstractionY(new ConcreateImplementorB());
            ray2.DoSth();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/NRatel/article/details/84539901