模式的定义

桥梁模式是一个比较简单的模式,其定义如下:

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

将抽象和实现解耦,使两者可以独立的变化。

类型

结构类

模式的使用场景

  • 不希望或不适用使用继承的场景
    例如继承层次过滤,无法更细化设计颗粒等场景,需要考虑使用桥梁模式
  • 接口或抽象类不稳定的场景
  • 重用性要求较高的场景
    设计的颗粒度越细,则被重用的可能性就越大,而采用继承则受父类的限制,不可能出现太细的颗粒度

优点

  • 抽象和实现分离
    这也是桥梁模式的主要特点,它完全是为了解决继承的缺点而提出的设计模式,在该模式下,实现可以不受抽象的约束,不用再绑定在一个固定的抽象层次上。
  • 优秀的扩充能力
  • 实现细节对用户透明
    用户不关心细节的实现,它已经由抽象导通过聚合关系完成了封装。

注意事项

桥梁模式是非常简单的,使用该模式时主要考虑如何拆分抽象和实现,并不是一涉及继承就要考虑使用该模式,那还要继承干什么呢?桥梁模式的意图还是对变化的封装,尽可能把变化的因素封装到最细,最小的逻辑单元中,避免风险的扩散。因此在进行系统设计时,发现类的继承有N层时,可以考虑使用桥梁模式。

UML类图

设计模式之桥梁模式--- Pattern Bridge_System

角色介绍

abstract—抽象化角色
它的主要职责是定义出该角色的行为,同时保存一个对实现化角色的引用,该角色一般是抽象类

RefinedAbstraction—修正抽象化角色
它引用实现对抽象化角色进行修正

Implementor—实现化角色
它是接口或者抽象类,定义角色必需的行为和属性

ConcreteImplementor—具体实现化角色

模式的通用源码

Implementor:

public interface Implementor {
    //基本方法
    public void doSomeThing();
    public void doAnyThing();
}

ConcreteImplementor1:

public class ConcreteImplementor1 implements Implementor {

    @Override
    public void doSomeThing() {
        // TODO Auto-generated method stub
        System.out.println("ConcreteImplementor1----doSomeThing()");
    }

    @Override
    public void doAnyThing() {
        // TODO Auto-generated method stub
        System.out.println("ConcreteImplementor1----doAnyThing()");
    }
}

ConcreteImplementor2:

public class ConcreteImplementor2 implements Implementor {


    @Override
    public void doSomeThing() {
        // TODO Auto-generated method stub
        System.out.println("ConcreteImplementor2----doSomeThing()");
    }

    @Override
    public void doAnyThing() {
        // TODO Auto-generated method stub
        System.out.println("ConcreteImplementor2----doAnyThing()");
    }
}

abstract:

public abstract class Abstraction {
    //定义对实现化角色的引用
    private Implementor implementor;

    public Abstraction(Implementor implementor) {
        super();
        this.implementor = implementor;
    }

    public void request(){
        implementor.doSomeThing();
    }
    //获得实现化角色
    public Implementor getImplementor() {
        return implementor;
    }
}

RefinedAbstraction:

public class RefinedAbstraction extends Abstraction {


    public RefinedAbstraction(Implementor implementor) {
        super(implementor);
        // TODO Auto-generated constructor stub
    }


    @Override
    public void request() {
        // TODO Auto-generated method stub
        System.out.println("RefinedAbstraction----request()");
        super.request();
        super.getImplementor().doAnyThing();
    }

}

Client:

public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Implementor implementor = new ConcreteImplementor1();       
        Abstraction abstraction = new RefinedAbstraction(implementor);
        abstraction.request();

        System.out.println("---------------------------------");
        implementor = new ConcreteImplementor2();
        abstraction = new RefinedAbstraction(implementor);
        abstraction.request();

    }
}

输出结果

RefinedAbstraction----request()
ConcreteImplementor1----doSomeThing()
ConcreteImplementor1----doAnyThing()
---------------------------------
RefinedAbstraction----request()
ConcreteImplementor2----doSomeThing()
ConcreteImplementor2----doAnyThing()

Android源码中的模式实现

uml图:

设计模式之桥梁模式--- Pattern Bridge_bridge_02

关键代码:

ListAdapter 接口:

//接口ListAdapter,定义了二个方法:areAllItemsEnabled,isEnabled
public interface ListAdapter extends Adapter {
    public boolean areAllItemsEnabled();
    boolean isEnabled(int position);
}

SimpleAdapter,CursorAdapter,ArrayAdapter都是ListAdapter 子类,实现了这二个定义的方法。

AbsListView 类:

public abstract class AbsListView extends AdapterView<ListAdapter> implements TextWatcher,
        ViewTreeObserver.OnGlobalLayoutListener, Filter.FilterListener,
        ViewTreeObserver.OnTouchModeChangeListener,
        RemoteViewsAdapter.RemoteAdapterConnectionCallback {
     ........
     ........
    /**
     * The adapter containing the data to be displayed by this view
     */
    ListAdapter mAdapter;//内聚ListAdapter对象
     ........
     ........
     //设置adapter
    public void setAdapter(ListAdapter adapter) {
        if (adapter != null) {
            mAdapterHasStableIds = mAdapter.hasStableIds();
            if (mChoiceMode != CHOICE_MODE_NONE && mAdapterHasStableIds &&
                    mCheckedIdStates == null) {
                mCheckedIdStates = new LongSparseArray<Integer>();
            }
        }

        if (mCheckStates != null) {
            mCheckStates.clear();
        }

        if (mCheckedIdStates != null) {
            mCheckedIdStates.clear();
        }
    }
     ........
     ........
}

AbsListView类有二个实现类分别为:ListView,GridView。

杂谈

类与类的关系主要还是继承(is-a)和聚合(have-a)的关系,继承(is-a)关系的子类必然是要受到父类的限制,如果继承次数过多的话会导致一些问题。
而聚合(have-a)关系是可以避免继承的这种父类的限制,并且也是可以实现这种继承(is-a)的功能的。
桥梁模式作为一种常用的设计模式,应当来说在设计模式中和我们常用开发中,是非常常见的。

参考资料

(1).设计模式之禅—第29章 桥梁模式
(2)桥梁模式
https://github.com/simple-android-framework/android_design_patterns_analysis/tree/master/bridge