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

Java设计模式之桥梁模式

作者头像
CoderJed
发布2018-09-30 10:21:41
4760
发布2018-09-30 10:21:41
举报
文章被收录于专栏:Jed的技术阶梯Jed的技术阶梯

梦想中的我自己,身价过亿,有两个大公司,一个是房地产公司,一个是服装制造公司,其实是什么公司我倒是不关心,我关心的是它赚不赚钱,赚了多少,这才是我关心的。先用类图表示一下我这两个公司:

代码如下:

代码语言:javascript
复制
public abstract class Corp {
    
    protected abstract void product();
    protected abstract void sell();
    
    /**
     * 先生产,再销售
     */
    public void makeMoney() {
        this.product();
        this.sell();
    }

}
代码语言:javascript
复制
public class HouseCorp extends Corp {

    @Override
    protected void product() {
        System.out.println("承建XX市XX小区...");
    }

    @Override
    protected void sell() {
        System.out.println("首付20万,海景别墅任意挑!");
    }
    
    @Override
    public void makeMoney() {
        super.makeMoney();
        System.out.println("房地产公司赚大钱咯!");
    }

}
代码语言:javascript
复制
public class ClothCorp extends Corp {

    @Override
    protected void product() {
        System.out.println("低奢新品牌服饰首发...");
    }

    @Override
    protected void sell() {
        System.out.println("买两件一件!");
    }
    
    @Override
    public void makeMoney() {
        super.makeMoney();
        System.out.println("服装公司赚小钱...");
    }

}

两个公司都有了,我肯定会关心两个公司的运营情况,我要知道它是生产什么的,赚多少钱,Client代码如下:

代码语言:javascript
复制
public class Client {

    public static void main(String[] args) {
        System.out.println("-------房地产公司是这个样子运行的-------");
        HouseCorp houseCorp = new HouseCorp();
        houseCorp.makeMoney();
        System.out.println();

        System.out.println("-------服装公司是这样运行的-------");
        ClothCorp clothCorp = new ClothCorp();
        clothCorp.makeMoney();
    }

}

运行结果:
-------房地产公司是这个样子运行的-------
承建XX市XX小区...
首付20万,海景别墅任意挑!
房地产公司赚大钱咯!

-------服装公司是这样运行的-------
低奢新品牌服饰首发...
买两件一件!
服装公司赚小钱...

我发现,服装公司赚的小钱满足不了我,我打算把服装公司改为IPad公司,修改类图如下:

IPad公司的代码如下:

代码语言:javascript
复制
public class IPadCorp extends Corp {

    @Override
    protected void product() {
        System.out.println("新IPad配置大升级!");
    }

    @Override
    protected void sell() {
        System.out.println("新IPad6期分期免息,还在等什么?");
    }
    
    @Override
    public void makeMoney() {
        super.makeMoney();
        System.out.println("苹果的产品果然赚钱!");
    }

}

为了查看公司运营情况,还需要修改Client的代码:

代码语言:javascript
复制
public class Client {

    public static void main(String[] args) {
        System.out.println("-------房地产公司是这个样子运行的-------");
        HouseCorp houseCorp = new HouseCorp();
        houseCorp.makeMoney();
        System.out.println();

        System.out.println("-------服装公司是这样运行的-------");
        IPadCorp ipadCorp = new IPadCorp();
        ipadCorp.makeMoney();
    }

}

确实,只用修改了几句话,我的服装厂就开始变成iPad生产车间,但是我制造了IPad,就不能制造服装了啊,那我以后想要制造MP4,改装后我的IPad就不能生产了啊,这样不行,成本太高了,于是我们修改一下类图:

代码如下:

代码语言:javascript
复制
/**
 * 整个公司的产品类
 */
public abstract class Product {
    
    public abstract void beProducted();
    public abstract void beSelled();

}
代码语言:javascript
复制
/**
 * 公司盖的房子
 */
public class House extends Product {

    @Override
    public void beProducted() {
        System.out.println("承建XX市XX小区...");
    }

    @Override
    public void beSelled() {
        System.out.println("首付20万,海景别墅任意挑!");
    }

}
代码语言:javascript
复制
/**
 * 公司制造的服装
 */
public class Cloth extends Product {

    @Override
    public void beProducted() {
        System.out.println("低奢新品牌服饰首发...");
    }

    @Override
    public void beSelled() {
        System.out.println("买两件送一件!");
    }

}
代码语言:javascript
复制
/**
 * 公司制造的IPad
 */
public class IPad extends Product {

    @Override
    public void beProducted() {
        System.out.println("新IPad配置大升级!");
    }

    @Override
    public void beSelled() {
        System.out.println("新IPad6期分期免息,还在等什么?");
    }

}
代码语言:javascript
复制
/**
 * 公司的抽象类
 */
public abstract class Corp {
    
    // 定义一个产品对象,具体是什么还不知道
    private Product product;
    
    // 构造函数,由子类定义传递具体的产品进来
    public Corp(Product product) {
        this.product = product;
    }
    
    // 赚钱的方式肯定都是一样的
    public void makeMoney() {
        this.product.beProducted();
        this.product.beSelled();
    }

}
代码语言:javascript
复制
/**
 * @description: 房地产公司盖房子
 */
public class HouseCorp extends Corp {
    
    public HouseCorp(House house) {
        super(house);
    }

    @Override
    public void makeMoney() {
        super.makeMoney();
        System.out.println("房地产公司赚大钱咯!");
    }

}
代码语言:javascript
复制
/**
 * @description: 制造公司搞制造,具体生产什么还不知道
 */
public class MakeCrop extends Corp {

    /**
     * 制造什么产品,等被调用的时候才知道
     */
    public MakeCrop(Product product) {
        super(product);
    }
    
    @Override
    public void makeMoney() {
        super.makeMoney();
        System.out.println("造啥都能赚钱!");
    }

}

HouseCorp类和MakeCorp类的区别是在有参构造的参数类型上,HouseCorp类比较明确,我就是只要House类,所以直接定义传递进来的必须是House类,一个类尽可能少的承担职责,那方法也是一样,既然HouseCorp类已经非常明确只生产House产品,那为什么不定义成House类型呢?MakeCorp就不同了,它是确定不了生产什么类型。

Client代码如下:

代码语言:javascript
复制
public class Client {

    public static void main(String[] args) {
        System.out.println("-------房地产公司是这个样子运行的-------");
        House house = new House();
        HouseCorp houseCorp = new HouseCorp(house);
        houseCorp.makeMoney();
        System.out.println();

        System.out.println("-------制造公司是这样运行的-------");
        MakeCorp makeCorp = new MakeCorp(new Cloth());
        makeCorp.makeMoney();
    }

}

运行结果:
-------房地产公司是这个样子运行的-------
承建XX市XX小区...
首付20万,海景别墅任意挑!
房地产公司赚大钱咯!

-------制造公司是这样运行的-------
低奢新品牌服饰首发...
买两件送一件!
造啥都能赚钱!

而现在想让制造公司制造IPad,这就非常简单了,代码如下:

代码语言:javascript
复制
public class Client {

    public static void main(String[] args) {
        System.out.println("-------房地产公司是这个样子运行的-------");
        House house = new House();
        HouseCorp houseCorp = new HouseCorp(house);
        houseCorp.makeMoney();
        System.out.println();

        System.out.println("-------制造公司是这样运行的-------");
        // 把制造服装的公司改为制造IPad就这么简单
        // MakeCorp makeCorp = new MakeCorp(new Cloth());
        MakeCorp makeCorp = new MakeCorp(new IPad());
        makeCorp.makeMoney();
    }

}

看上面的代码,就修改了一句代码就完成了生产产品的转换。我们深入的思考一下,我现在只有房地产公司和制造公司,以后我还要开其他公司这么办?新增加公司对我们上面的类图没有大的修改,充其量是扩展:

  • 增加公司,要么继承Corp类,要么继承HouseCorp或MakeCorp,不用再修改原有的类了;
  • 增加产品,继承Product类,或者继承House类,你要把房子分为公寓房、别墅、商业用房等等;

你都是在扩展,唯一你要修改的就是Client类,也就是说Corp类和Product类都可以自由的扩展,而不会对整个应用产生太的变更,这就是桥梁模式。

为什么叫桥梁模式?我们看一下桥梁模式的通用类图:

看到中间那根带箭头的线了吗?是不是类似一个桥,连接了两个类?所以就叫桥梁模式。 我们再把桥梁模式的几个概念熟悉一下,我把Corp类以及它的两个实现类放到了Abstraction包中,把House以及相关的三个实现类放到了Implementor包中,这两个包分别对应了桥梁模式的业务抽象角色(Abstraction)和业务实现角色(Implementor),这两个角色大家只要记住一句话就成:业务抽象角色引用业务实现角色,或者说业务抽象角色的部分实现是由业务实现角色完成的,很简单,别想那么复杂了。

桥梁模式的优点就是类间解耦,我们上面已经提到,两个角色都可以自己的扩展下去,不会相互影响,这个也符合OCP原则。

本文原书: 《您的设计模式》 作者:CBF4LIFE

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.09.25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

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