文档章节

设计模式(六)桥梁模式

 小鲜肉成长记
发布于 2017/07/21 09:49
字数 2000
阅读 3
收藏 0

概念

桥梁模式是对象的结构模式,又称为柄体模式或接口模式。桥梁模式的用意是“将抽象化(Abstraction)与实现(Implementation)脱耦,使得二者可以独立的变化”。将两个角色之间的继承关系改为聚合关系,就是将他们之间的强关联改为弱关联,也就是说抽象化和实现之间使用组合/聚合关系而不是继承关系,满足组合/聚合复用原则。

模式结构

两个等级结构

  • 抽象化角色和修正抽象化角色组成抽象化等级结构
  • 实现角色和具体实现角色组成实现化等级结构

对应角色

  • 抽象化角色(Abstraction):抽象化给出的定义,并保存一个对实现化对象的引用
  • 修正抽象化角色(RefinedAbstraction):扩展抽象化角色,改变和修正父类对抽象化的定义
  • 实现化角色(Implementor):给出实现化角色的接口,但不给出具体的实现。这个角色与抽象化角色给出的接口可以非常不一样
  • 具体实现化角色(ConcreteImplementor):给出实现化角色接口的具体实现

抽象化等级结构中的方法通过向对应的实现化对象的委派来实现自己的功能,抽象化角色可以通过向不同的实现化对象委派来动态的转换自己的功能目的。

/**
 * 抽象化角色:声明了operation方法,并给出了它的实现,该实现是通过向实现化对象的委派(调用operationImpl()方法)实现
 */
public abstract class Abstraction {
    protected Implementor impl;

    public Abstraction(Implementor impl) {
        this.impl = impl;
    }

    public void operation(){
        impl.operationImpl();
    }
    // 其他的操作方法
    public void otherOperation(){
    }
}

/**
 * 修正抽象化角色
 */
class RefinedAbstraction extends Abstraction{

    public RefinedAbstraction(Implementor impl) {
        super(impl);
    }
}

/**
 * 实现化角色:实现抽象部分需要的某些具体功能
 */
abstract class Implementor{
    public abstract void operationImpl();
}

/**
 * 具体实现化A
 */
class ConcreteImplementorA extends Implementor{
    @Override
    public void operationImpl() {
        System.out.println("具体实现化A");
    }
}

/**
 * 具体实现化B
 */
class ConcreteImplementorB extends Implementor{
    @Override
    public void operationImpl() {
        System.out.println("具体实现化B");
    }
}

class BridgeClient{
    public static void main(String[] args){
        Implementor impl = new ConcreteImplementorA();
        Abstraction abstraction = new RefinedAbstraction(impl);
        abstraction.operation();

        //把实现方式切换为B调用
        impl = new ConcreteImplementorB();
        abstraction = new RefinedAbstraction(impl);
        abstraction.operation();
    }
}
运行结果:

具体实现化A
具体实现化B

抽象化角色的接口比实现化接口角色的接口宽。

示例说明

公司的行政部门有消息需要告知公司同事。需求第一步:通过短信向全体同事发送普同消息;需求第二步:通过短信向部门leader发送紧急消息;需求第三步:通过邮件向全体同事发送普通消息;需求第四步:通过邮件向部门leader发送紧急消息。这样一个需求,从根本上来说分为两个维度:消息类型+发送方式,将来可能还会增加其他类型和方式,必须做到易于扩展。利用桥梁模式解决这一问题。


首先进行等级结构划分

抽象化等级结构:发送消息的方式

实现化等级结构:发送消息的类型

定义实现化接口:发送消息类型

第一步:实现短信方式发送普通消息

/**
* 发送消息实现化接口-发送方式
*/
interface MessageImplementor{
    void send(String message, String toUser);
}
定义抽象化接口机机器方法
/**
 * 消息类型抽象化接口:例如:普通消息,紧急消息
 */
public abstract class AbstractionMessage {
    MessageImplementor impl;

    public AbstractionMessage(MessageImplementor impl) {
        this.impl = impl;
    }

    public void sendMessage(String message, String toUser){
        impl.send(message, toUser);
    }
}
修正抽象化接口1:普通消息
/**
 * 发送普通消息-修正消息类型抽象化接口1
 */
class CommonMessage extends AbstractionMessage{
    public CommonMessage(MessageImplementor impl) {
        super(impl);
    }

    @Override
    public void sendMessage(String message, String toUser) {
        super.sendMessage(message, toUser);//普通消息调用父类接口即可
    }
}
具体实现1:短信方式发送
/**
 * 发送手机短信-实现化接口具体实现1
 */
class MessageSMS implements MessageImplementor{
    @Override
    public void send(String message, String toUser) {
        System.out.println("收到短信消息:"+toUser+","+message);
    }
}

客户端

class MessageClient{
    public static void main(String[] args){
        MessageImplementor impl = new MessageSMS();
        AbstractionMessage message = new CommonMessage(impl);
        message.sendMessage("今年国庆假期按照国家法定假日休假", "全体同事");
    }
}
发送普通短信消息,运行结果

收到短信消息:全体同事,今年国庆假期按照国家法定假日休假

实现其他类型或方式,只需要增加对应的修正抽象类接口和具体的实现类,客户端进行调用即可,新增加内容与已有内容互相独立,互不影响。

第二步:实现短信方式发送紧急消息

/**
 * 发送紧急消息-修正消息类型抽象化接口2
 */
class UrgencyMessage extends AbstractionMessage{
    public UrgencyMessage(MessageImplementor impl) {
        super(impl);
    }

    @Override
    public void sendMessage(String message, String toUser) {
        message = "紧急—" + message;
        super.sendMessage(message, toUser);
    }
    //紧急消息在普通消息的基础上增加新功能
    public void replyMessage(){
        System.out.println("收到紧急消息");
    }
}
增加客户端调用方法
message = new UrgencyMessage(impl);
message.sendMessage("本周末召开紧急会议,各部门leader收到请回复", "各部门leader");
运行结果:

收到短信消息:全体同事,今年国庆假期按照国家法定假日休假
收到短信消息:各部门leader,紧急—本周末召开紧急会议,各部门leader收到请回复

第三步,第四步:增加邮件方式发送

由于已经实现了发送普通消息和紧急消息的代码,只需要增加邮件方式发送的具体实现,即可同时实现第三四步的需求。

/**
 * 发送邮件-实现化接口具体实现2
 */
class MessageEmail implements MessageImplementor{
    @Override
    public void send(String message, String toUser) {
        System.out.println("收到邮件消息:"+toUser+","+message);
    }
}
客户端代码:
class MessageClient{
    public static void main(String[] args){
        MessageImplementor impl = new MessageSMS();
        AbstractionMessage message = new CommonMessage(impl);
        message.sendMessage("今年国庆假期按照国家法定假日休假", "全体同事");
        message = new UrgencyMessage(impl);
        message.sendMessage("本周末召开紧急会议,各部门leader收到请回复", "各部门leader");
        // 实现方式切换为邮件方式
        impl = new MessageEmail();
        message = new CommonMessage(impl);
        message.sendMessage("今年国庆假期按照国家法定假日休假", "全体同事");
        message = new UrgencyMessage(impl);
        message.sendMessage("本周末召开紧急会议,各部门leader收到请回复", "各部门leader");
    }
}
运行结果:

收到短信消息:全体同事,今年国庆假期按照国家法定假日休假
收到短信消息:各部门leader,紧急—本周末召开紧急会议,各部门leader收到请回复
收到邮件消息:全体同事,今年国庆假期按照国家法定假日休假
收到邮件消息:各部门leader,紧急—本周末召开紧急会议,各部门leader收到请回复

桥梁模式解析:通过在不同东西之间搭建一个桥,让它们之间有连接,可以互相通信和使用——为分离的抽象部分和实现部分搭建桥梁。桥接是单向的,只能是抽象部分的对象去使用具体实现的部分对象,不能反着来。如果是一个维度的话用继承直接实现即可,但是两个维度如果用继承(两个维度数相乘)需要实现的类比桥梁方式(两个维度数相加)多。

桥梁模式很好的实现了开闭原则和对用对象组合少用对象继承原则。

桥梁模式优缺点

  • 分离抽象和实现:提高系统的灵活性,有助于对系统进行分层。
  • 更好的扩展性:抽象和实现分开,并且分别定义了接口,使抽象和实现可以独立的扩展,而互相不影响。
  • 动态切换实现:运行期间可以动态的切换实现
  • 可减少子类的个数:相对于继承来说,子类数由“乘积”变为“和”

后面几个有点都是基于第一条:分离抽象和实现。

© 著作权归作者所有

粉丝 0
博文 12
码字总数 14860
作品 0
东城
私信 提问
设计模式 2014-12-19

book: 阎宏《JAVA与模式》 架构设计栏目 http://blog.csdn.net/enterprise/column.html 概要: http://bbs.csdn.net/forums/Embeddeddriver 23种设计模式分别是: 1.单例模式 2.工厂方法模式...

jayronwang
2014/12/19
293
0
JavaScript 的一些设计模式

设计模式的定义:在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案 设计模式是前人解决某个特定场景下对而总结出来的一些解决方案。可能刚开始接触编程还没有什么经验的时候,会...

格西南
08/20
0
0
【设计模式笔记】(十六)- 代理模式

一、简述 代理模式(Proxy Pattern),为其他对象提供一个代理,并由代理对象控制原有对象的引用;也称为委托模式。 其实代理模式无论是在日常开发还是设计模式中,基本随处可见,中介者模式中...

MrTrying
2018/06/24
0
0
EasyToLearnDesignPattern

简单上手设计模式 GITHUB:https://github.com/Fisher-Joe/EasyToLearnDesignPattern 本文旨在使用最简单的语言,最简单的代码让人学习设计模式(最起码是我) 说明: 本文的所有内容都是基于...

芝麻开门
04/19
0
0
(目录)设计模式(可复用面向对象软件的基础)

本系列“设计模式”博客使用Golang语言实现算法。所谓算法是指解决一个问题的步骤,个人觉得不在于语言。小弟只是最近学习Golang,所以顺带熟练一下语法知识,别无它意。 本系列博客主要介绍...

chapin
2015/01/13
157
0

没有更多内容

加载失败,请刷新页面

加载更多

关于AsyncTask的onPostExcute方法是否会在Activity重建过程中调用的问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/XG1057415595/article/details/86774575 假设下面一种情况...

shzwork
56分钟前
5
0
object 类中有哪些方法?

getClass(): 获取运行时类的对象 equals():判断其他对象是否与此对象相等 hashcode():返回该对象的哈希码值 toString():返回该对象的字符串表示 clone(): 创建并返此对象的一个副本 wait...

happywe
今天
6
0
Docker容器实战(七) - 容器中进程视野下的文件系统

前两文中,讲了Linux容器最基础的两种技术 Namespace 作用是“隔离”,它让应用进程只能看到该Namespace内的“世界” Cgroups 作用是“限制”,它给这个“世界”围上了一圈看不见的墙 这么一...

JavaEdge
今天
8
0
文件访问和共享的方法介绍

在上一篇文章中,你了解到文件有三个不同的权限集。拥有该文件的用户有一个集合,拥有该文件的组的成员有一个集合,然后最终一个集合适用于其他所有人。在长列表(ls -l)中这些权限使用符号...

老孟的Linux私房菜
今天
7
0
面试套路题目

作者:抱紧超越小姐姐 链接:https://www.nowcoder.com/discuss/309292?type=3 来源:牛客网 面试时候的潜台词 抱紧超越小姐姐 编辑于 2019-10-15 16:14:56APP内打开赞 3 | 收藏 4 | 回复24 ...

MtrS
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部