Java 设计模式(15) —— 桥接模式

一、桥接模式

将实现与抽象放在两个不同的类层次中,使两个层次可以独立改变

桥接模式

二、示例

电视机遥控器项目:假设电视机的遥控器都是统一的开关、加、减的3个按钮,则不同品牌的电视机需要对这3个按钮进行各自的功能实现

使用传统的面向对象模式结合超类的接口实现

1.定义遥控器内部用到的统一方法接口

/**
 * 桥接模式,将遥控器所有需要用到的方法进行统一定义
 */
public interface Control {

    public void On();

    public void Off();

    public void setChannel(int ch);

    public void setVolume(int vol);

}

2.不同的遥控器厂家对接口进行实现


/**
 * 桥接模式,LG遥控器对遥控器统一方法的实现
 */
public class LGControl implements Control {

    @Override
    public void On() {
        System.out.println("**Open LG TV**");
    }

    @Override
    public void Off() {
        System.out.println("**Off LG TV**");
    }

    @Override
    public void setChannel(int ch) {
        System.out.println("**The LG TV Channel is setted " + ch + "**");
    }

    @Override
    public void setVolume(int vol) {
        System.out.println("**The LG TV Volume is setted " + vol + "**");
    }

}

/**
 * 桥接模式,Sony遥控器对遥控器统一方法的实现
 */
public class SonyControl implements Control {

    @Override
    public void On() {
        System.out.println("*Open Sony TV*");
    }

    @Override
    public void Off() {
        System.out.println("*Off Sony TV*");
    }

    @Override
    public void setChannel(int ch) {
        System.out.println("*The Sony TV Channel is setted " + ch + "*");
    }

    @Override
    public void setVolume(int vol) {
        System.out.println("*The Sony TV Volume is setted " + vol + "*");
    }

}

3.定义统一的电视遥控器界面上的接口


/**
 * 面向对象模式,所有遥控器统一的界面,界面上定义3个统一的按钮
 */
public interface TvControl {

    public void Onoff();

    public void nextChannel();

    public void preChannel();
}

4.不同的电视机厂家对遥控器界面按钮的功能实现


/**
 * 面向对象模式,定义厂家的遥控器对象,实现厂家制定的遥控器方法
 */
public class LGTvControl extends LGControl implements TvControl {
    private static int ch = 0;
    private static boolean ison = false;

    public void Onoff() {
        if (ison) {
            ison = false;
            super.Off();
        } else {
            ison = true;
            super.On();
        }
    }

    public void nextChannel() {
        ch++;
        super.setChannel(ch);
    }

    public void preChannel() {
        ch--;
        if (ch < 0) {
            ch = 200;
        }
        super.setChannel(ch);
    }

}

5.对外调用输出


/**
 * 传统面向对象的模式
 */
public class MainTest {
    public static void main(String[] args) {
        LGTvControl mLGTvControl=new LGTvControl();
        SonyTvControl mSonyTvControl=new SonyTvControl();
        
        mLGTvControl.Onoff();
        mLGTvControl.nextChannel();
        mLGTvControl.nextChannel();
        mLGTvControl.preChannel();
        mLGTvControl.Onoff();
        
        mSonyTvControl.Onoff();
        mSonyTvControl.preChannel();
        mSonyTvControl.preChannel();
        mSonyTvControl.preChannel();
        mSonyTvControl.Onoff();
    }
}

三、桥接模式改进

如果现在要新增电视机厂家或新增遥控器种类,则极不利于拓展。

观察可以发现虽然不同厂家的电视遥控器品牌不同,但是内部功能的调用是一样的。如果随着品牌的增加,则需要给每个品牌制定一款遥控器实现的对象。因此可以将遥控器的调用模式抽象出来统一调用,如果有新的调用方法,也同理进行抽象实现

1.定义统一的抽象类


/**
 * 桥接模式,桥接的抽象类,定义基本的抽象方法可桥接对象
 */
public abstract class TvControlabs {

    Control mControl = null;

    public TvControlabs(Control mControl) {
        this.mControl = mControl;
    }

    public abstract void Onoff();

    public abstract void nextChannel();

    public abstract void preChannel();


}

2.定义相同实现方式的桥接对象,对抽象类的方法进行实现


/**
 * 桥接模式,基础遥控器的方法实现
 */
public class TvControl extends TvControlabs {
    private int ch = 0;
    private boolean ison = false;

    public TvControl(Control mControl) {
        super(mControl);
    }

    @Override
    public void Onoff() {
        if (ison) {
            ison = false;
            mControl.Off();
        } else {
            ison = true;
            mControl.On();
        }

    }

    @Override
    public void nextChannel() {
        ch++;
        mControl.setChannel(ch);

    }

    @Override
    public void preChannel() {
        ch--;
        if (ch < 0) {
            ch = 200;
        }
        mControl.setChannel(ch);

    }

}

3.若有新类型的统一的遥控器出现,直接在基础类上进行拓展实现


/**
 * 桥接模式,新电视机类型,实现基础抽象方法,以及新型的遥控器的方法
 */
public class newTvControl extends TvControlabs {
    private int ch = 0;
    private boolean ison = false;
    private int prech = 0;

    public newTvControl(Control mControl) {
        super(mControl);
    }

    @Override
    public void Onoff() {
        if (ison) {
            ison = false;
            mControl.Off();
        } else {
            ison = true;
            mControl.On();
        }

    }

    @Override
    public void nextChannel() {
        prech = ch;
        ch++;
        mControl.setChannel(ch);

    }

    @Override
    public void preChannel() {
        prech = ch;
        ch--;
        if (ch < 0) {
            ch = 200;
        }
        mControl.setChannel(ch);

    }


    public void setChannel(int nch) {
        prech = ch;
        ch = nch;
        mControl.setChannel(ch);

    }

    public void Back() {
        mControl.setChannel(prech);
    }
}

4.定义遥控器时直接传入需要用到的控制器种类即可

/**
 * 桥接模式
 * 通过抽象类定义需要用到的方法抽象以及拓展方法的实现
 * 接口定义底层有的所有功能方法
 * 不同的对象实现不同的接口方法
 * 将实现接口的对象引入到抽象类中
 */
public class MainTest {
    public static void main(String[] args) {
        TvControl mLGTvControl;
        TvControl mSonyTvControl;
        
        // 定义统一的基础遥控器,传入不同的厂家控制器则实现不同的方法
        mSonyTvControl = new TvControl(new SonyControl());
        mLGTvControl = new TvControl(new LGControl());
        mLGTvControl.Onoff();
        mLGTvControl.nextChannel();
        mLGTvControl.nextChannel();
        mLGTvControl.preChannel();
        mLGTvControl.Onoff();

        mSonyTvControl.Onoff();
        mSonyTvControl.preChannel();
        mSonyTvControl.preChannel();
        mSonyTvControl.preChannel();
        mSonyTvControl.Onoff();

        // 定义统一新型的遥控器,传入不同的厂家控制器则实现不同的方法
        newTvControl mSharpTvControl;
        mSharpTvControl = new newTvControl(new SharpControl());
        mSharpTvControl.Onoff();
        mSharpTvControl.nextChannel();
        mSharpTvControl.setChannel(9);
        mSharpTvControl.setChannel(28);
        mSharpTvControl.Back();
        mSharpTvControl.Onoff();

    }
}

四、总结

  • 系统有多维角度分类时,而每一种分类又有可能变化,考虑使用桥接模式
  • 桥接的目的是分离抽象与实现,使抽象和实现可以独立变化。
  • 桥接的目的是让底层实现和上层接口可以分别演化,从而提高移植性
  • 桥接模式是往往是为了利用已有的方法或类
  • 桥接模式强调接口对象仅提供基本操作


Java设计模式所有示例代码,持续更新中

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1 场景问题# 1.1 发送提示消息## 考虑这样一个实际的业务功能:发送提示消息。基本上所有带业务流程处理的系统...
    七寸知架构阅读 10,518评论 5 63
  • 设计模式汇总 一、基础知识 1. 设计模式概述 定义:设计模式(Design Pattern)是一套被反复使用、多...
    MinoyJet阅读 9,389评论 1 15
  • 文章部分内容转载自:http://blog.csdn.net/zhangerqing 一、设计模式的分类 总体来说...
    j_cong阅读 6,243评论 0 20
  • 江湖如梦,侠客多情。 茶馆里的说书人不知哪来的小道消息,唾液横飞的抬着案板道着那让人笑出声的世道。 传言采花贼长得...
    沈长旌阅读 1,501评论 0 0
  • 不知从何时开始,很期待家的温暖,家里的温情,每个人之间的相互关爱。记忆之间,从未得到,所以期待! 很小的时候,我都...
    深深浅浅间阅读 3,505评论 3 3