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设计模式所有示例代码,持续更新中

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容

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