设计模式之桥梁模式

220 阅读3分钟

案例:公司经营,张三经营着两个公司,一个是房地产公司,一个是服装制造公司。

类图:

代码:

public abstract class Corp {

    protected abstract void product();
    protected abstract void sell();

    /**
     * 赚钱方法:先生产,再销售
     */
    public void makeMoney() {
        this.product();
        this.sell();
    }

}

public class HouseCorp extends Corp {

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

    @Override
    protected void sell() {
        System.out.println("卖房...");
    }

    @Override
    public void makeMoney() {
        super.makeMoney();
        System.out.println("房地产公司盈利两千万...");
    }
}

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("服装公司盈利一百万...");
    }
}

public class Client {

    public static void main(String[] args) {

        HouseCorp houseCorp = new HouseCorp();
        houseCorp.makeMoney();

        ClothCorp clothCorp = new ClothCorp();
        clothCorp.makeMoney();

    }

}

张三感觉服装公司盈利太少,于是把服装公司转型为制造iPad的公司,修改类图:

修改代码:

public class IPadCorp extends Corp {

    @Override
    protected void product() {
        System.out.println("生产iPad...");
    }

    @Override
    protected void sell() {
        System.out.println("销售iPad...");
    }

    @Override
    public void makeMoney() {
        super.makeMoney();
        System.out.println("iPad公司盈利一千万...");
    }
}

public class Client {

    public static void main(String[] args) {

        HouseCorp houseCorp = new HouseCorp();
        houseCorp.makeMoney();

        // ClothCorp clothCorp = new ClothCorp();
        // clothCorp.makeMoney();

        IPadCorp iPadCorp = new IPadCorp();
        iPadCorp.makeMoney();

    }

}

这样确实实现了张三的需求,但存在的问题是:原来的服装公司彻底失去了制造和销售服装的功能,即没有保留原有的功能,如果以后再对iPad公司进行改造,让其制造和销售电脑,那么制造iPad的功能也会彻底丢失,张三感觉这样做成本太大了。

由此,我们引入桥梁模式。新的类图如下:

代码:

public abstract class Product {

    public abstract void beProducted();
    public abstract void beSelled();

}

public class House extends Product {

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

    @Override
    public void beSelled() {
        System.out.println("销售楼房...");
    }
}

public class Cloth extends Product {

    @Override
    public void beProducted() {
        System.out.println("潮牌服装制造...");
    }

    @Override
    public void beSelled() {
        System.out.println("出售潮牌服装...");
    }
}

public class IPad extends Product {

    @Override
    public void beProducted() {
        System.out.println("生产iPad...");
    }

    @Override
    public void beSelled() {
        System.out.println("销售iPad...");
    }
}

public abstract class Corp {

    // 定义一个产品对象
    private Product product;

    // 构造函数,由子类定义传递具体的产品进来
    public Corp(Product product) {
        this.product = product;
    }

    public void makeMoney() {
        this.product.beProducted();
        this.product.beSelled();
    }

}

public class HouseCorp extends Corp {

    public HouseCorp(Product product) {
        super(product);
    }

    @Override
    public void makeMoney() {
        super.makeMoney();
        System.out.println("房地产公司盈利两千万...");
    }

}

public class MakeCrop extends Corp {

    // 具体制造什么产品还不知道,调用的时候才知道
    public MakeCrop(Product product) {
        super(product);
    }

    @Override
    public void makeMoney() {
        super.makeMoney();
        System.out.println("制造公司盈利五百万...");
    }
}


public class Client {

    public static void main(String[] args) {

        House house = new House();
        HouseCorp houseCorp = new HouseCorp(house);
        houseCorp.makeMoney();


        Cloth cloth = new Cloth();
        IPad iPad = new IPad();

        MakeCrop makeCrop = new MakeCrop(cloth);
        makeCrop.makeMoney();

        makeCrop = new MakeCrop(iPad);
        makeCrop.makeMoney();

    }

}

在代码中,HouseCorp类和MakeCorp类的区别是在有参构造器的参数类型上,HouseCorp类很明确自身职能,就是生产和制造House,所以直接传入House的对象,MakeCorp由于不确定具体制造和销售什么产品,所以传入的参数为Product抽象类类型。

这就是桥梁模式。总结:

  • 桥梁模式具有很好的扩展性,如果要增加公司,可以直接继承Corp类或者HouseCorp类和MakeCrop类;如果要增加产品,直接继承Product类或者继承已有的产品实现类(比如要把房子再分为商用房、居住房等类型)
  • 桥梁模式降低了类之间的耦合性

桥梁模式的通用类图如下:

  • Abstraction:业务抽象角色,案例中的Corp、HouseCorp和MakeCrop
  • Implementor:业务实现角色,案例中的Product、House、Cloth、IPad
  • 业务抽象角色引用业务实现角色,或者说,业务抽象角色的部分实现是由业务实现角色完成的

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