前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java设计模式(九)桥接模式

Java设计模式(九)桥接模式

作者头像
每天学Java
发布2020-06-01 18:04:25
6860
发布2020-06-01 18:04:25
举报
文章被收录于专栏:每天学Java每天学Java

我是在脑壳疼的情况下(今天的工作的量很大,内容很丰富,我很开心,以至于脑壳疼)写下这篇关于桥接模式的文章,不正之处请多指教。

何谓桥接模式,用一座桥连接起来的模式,珠港澳大桥连接了中国香港、珠海和中国澳门,在一开始的时候他们三之间都是隔海相望,相互独立,但是他们三连起来了,相互独立又彼此关联,所以这里我把中国比做一个接口(跟珠港澳并没有关系,哈哈),那么实现了这个接口的城市就是属于中国,这是一个具体的实现类,每一个城市每年都有自己城市的发展规划,这个规划比较抽象,我们就当成抽象类。那么我想问一下中国有多少个城市?每个城市的每年发展是一样的吗?如果按照正常的逻辑来走,我们写一个城市的实现类,然后还要写每一个哪一年的城市规划。就像下面这样:

代码语言:javascript
复制
class Country {
    protected void city() {
        System.out.println("中国");
    }

}

class HeNan extends Country {

    @Override
    public void city() {
        System.out.println("中国河南省,2017河南的年度计划发展经济");
    }
}

class ZheJiang extends Country {

    @Override
    public void city() {
        System.out.println("中国浙江省,2017浙江的年度计划是增加城市形象");
    }
}

那2018,2019,2020,2021呢?每年都继承一下吗,这样下去继承关系就过于复杂了,而且如果年度规划发生变化,或者城市发生变化,我们就要对这个类进行改写,这不符合单一职责原则。怎么办呢?因为涉及到两个纬度:城市和年度规划,所以你就要考虑桥接模式了,如果你不知道桥接模式那么现在你知道了。所以我们还是先看一下桥接模式的概念

桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。 这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。

什么叫抽象化和实现化呢? 在我的例子中:年规划是抽象化,城市是实现化。桥接模式是如何实现解耦,如何把他们分离出来独立变化呢?概念上说通过提供桥接来实现。

我们先忘掉桥接模式,试着写一下代码,首先把抽象和实现分离:也就是说,计划和城市分离开。先写城市

代码语言:javascript
复制
interface Country1 {
    String city();
}

class Province implements Country1 {
    String name;

    public Province(String name) {
        this.name = name;
    }

    @Override
    public String city() {
        return name;
    }
}

这样看过来是不是就符合了单一职责的原则,如果要改这个类,原因肯定跟年度计划没有关系。那我们继续往下看。有了实体化,那就该抽象化了吧。这个抽象的类就是那座桥,左边是中国城市,右边是年度计划,你们两边想怎么就怎么玩,我把你们打通就好了,怎么打通呢?引入Country1这个接口当作构造参数,不然的话桥连不上这边城市啊,那么年度计划这个类实现我这个抽象类,那么你必然要重写我的方法,引入构造器,这样一来两边可以随意变动。

代码语言:javascript
复制
abstract class AbstractYearPlan {
    protected Country1 country;

    protected AbstractYearPlan(Country1 country) {
        this.country = country;
    }

    protected abstract void drawYearPlan();
}

class YearPlan extends AbstractYearPlan {
    private String planDescript;

    protected YearPlan(String planDescript, Country1 country) {
        super(country);
        this.planDescript = planDescript;
    }

    @Override
    protected void drawYearPlan() {
        String val = country.city() + "," + planDescript;
        System.out.println(val);
    }
}

看一下main函数:

代码语言:javascript
复制
 new YearPlan("2017年我要发展经济", new Province("河南省")).drawYearPlan();
 new YearPlan("2017年我要增加城市形象", new Province("浙江省")).drawYearPlan();

这样一来我们就实现了一个桥接模式模式。年度计划和城市可以任意组合,而不必像开始那样不断的继承来达到效果,此外我们可以使用静态资源或者枚举进行计划和城市两个参数的填充。

老规矩,来看一下理论知识:

意图:将抽象部分与实现部分分离,使它们都可以独立的变化。

主要解决:在有多种可能会变化的情况下,用继承会造成类爆炸问题,扩展起来不灵活。

何时使用:实现系统可能有多个角度分类,每一种角度都可能变化。

如何解决:把这种多角度分类分离出来,让它们独立变化,减少它们之间耦合。

关键代码:抽象类依赖实现类。

应用实例: 1、猪八戒从天蓬元帅转世投胎到猪,转世投胎的机制将尘世划分为两个等级,即:灵魂和肉体,前者相当于抽象化,后者相当于实现化。生灵通过功能的委派,调用肉体对象的功能,使得生灵可以动态地选择。 2、墙上的开关,可以看到的开关是抽象的,不用管里面具体怎么实现的。

优点: 1、抽象和实现的分离。 2、优秀的扩展能力。 3、实现细节对客户透明。

缺点:桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。

使用场景: 1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。 2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。 3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。

注意事项:对于两个独立变化的维度,使用桥接模式再适合不过了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-10-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 每天学Java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档