桥接模式

Posted 纪煜楷

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了桥接模式相关的知识,希望对你有一定的参考价值。

  桥接模式(Bridge Pattern)是用于把抽象化与实现化解耦,使得二者可以独立变化,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦
  桥接模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响
  场景:
  Company抽象:XX公司的盈利模式是生产产品,销售产品获得利润,把XX公司当做一个标准的盈利抽象,
  子公司实现:其所有的子公司都实现这套抽象,比如房产,造车,衣服的子公司,统一实现接口后生产产品,销售产品
  子公司改造:此时如果衣服行业不景气,想改造成卖饮料的公司,则需要对原有的衣服类做改造,违背了开闭原则,示例如下:
 
    Company抽象
/**
 * 公司抽象类
 * @author test11
 */
public abstract class Company {

    /**
     * 生产商品
     */
    public abstract void produce();

    /**
     * 销售商品
     */
    public abstract void sell();

    /**
     * 盈利模式
     */
    public void earnMoney(){
        this.produce();

        this.sell();
    }

}

  房地产公司

/**
 * 房地产公司
 * @author test11
 */
public class HouseCompany extends Company{

    @Override
    public void produce() {
        System.out.println("建房");
    }

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

    @Override
    public void earnMoney() {
        super.earnMoney();
    }
}

  造车公司

/**
 * 汽车公司
 * @author test11
 */
public class CarCompany extends Company{

    @Override
    public void produce() {
        System.out.println("造车");
    }

    @Override
    public void sell() {
        System.out.println("卖车");
    }

    @Override
    public void earnMoney() {
        super.earnMoney();
    }
}

  衣服公司改造成饮料公司

/**
 * 综合业务
 * 原本生产衣服的子公司,改造成生产饮料的,则需要对原有的代码做改动,违背了开闭原则
 * @author test11
 */
public class CombineCompany extends Company{


    @Override
    public void produce() {
        //System.out.println("生产衣服");
        System.out.println("生产饮料");
    }

    @Override
    public void sell() {
        //System.out.println("销售衣服");
        System.out.println("卖饮料");
    }

    @Override
    public void earnMoney() {
        super.earnMoney();
    }
}

   测试不同公司赚钱方式

/**
 * 测试不同公司赚钱方式
 * @author test11
 */
public class Demo {

    public static void main(String[] args) {
        //房地产
        Company house = new HouseCompany();
        house.earnMoney();

        //智能汽车
        Company car = new CarCompany();
        car.earnMoney();

        //综合业务
        /**
         * 综合业务这里每次更换盈利的商品,都得对原有类进行修改,违反了开闭原则
         * 此时可通过把公司和产品分开,在综合公司类传入新产品,公司无需关注是什么新产品
         * 只需调用传入产品的生成和销售方法即可,实现了公司和产品的解耦
         */
        Company combine = new CombineCompany();
        combine.earnMoney();
    }
}

  综上,我们希望将抽象与实现部分分离,使它们都可以独立的变化,避免在有多种可能会变化的情况下,扩展起来不灵活

    上面例子的痛点在于,每当公司变更生产其他产品,则需要改动原有的产品实现类,违背了开闭原则,此时我们希望把产品抽象出来,对于不同的公司实现,传入不同的产品进行生产销售,这样即使发生了产品变更,只需要定义好新的产品,作为参数传入即可

  我们试图把产品和公司这两个耦合的对象分离开来,产品实现自代工厂Product抽象,代工厂定义生产和销售的标准接口,公司实现自Company抽象,定义好接收产品并且销售产品的抽象,然后在代工厂和公司之间搭建输送产品的桥梁即可,见如下示例

  代工厂Product

/**
 * 将产品抽象出来
 * @author test11
 */
public abstract class Product {

    /**
     * 生产商品
     */
    public abstract void produce();

    /**
     * 销售商品
     */
    public abstract void sell();

}

  各类产品实现

/**
 * 盈利的产品-房子
 * @author test11
 */
public class House extends Product{

    @Override
    public void produce() {
        System.out.println("建房");
    }

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

}
package com.design.model.designmodel.bridge;

/**
 * 盈利的商品-汽车
 * @author test11
 */
public class Car extends Product{

    @Override
    public void produce() {
        System.out.println("造车");
    }

    @Override
    public void sell() {
        System.out.println("卖车");
    }

}
package com.design.model.designmodel.bridge;

/**
 * 盈利的商品-饮料
 * @author test11
 */
public class Drink extends Product{

    @Override
    public void produce() {
        System.out.println("生产饮料");
    }

    @Override
    public void sell() {
        System.out.println("销售饮料");
    }
}
/**
 * 盈利的商品-衣服
 * @author test11
 */
public class Cloth extends Product{

    @Override
    public void produce() {
        System.out.println("生产衣服");
    }

    @Override
    public void sell() {
        System.out.println("销售衣服");
    }
}

  公司抽象和实现

/**
 * 公司抽象类
 * @author test11
 */
public abstract class Company {

    Product product;

    Company(Product product){
        this.product = product;
    }

    /**
     * 盈利模式
     */
    public void earnMoney(){
        this.product.produce();
        this.product.sell();
    }

}
/**
 * 房地产公司
 * @author test11
 */
public class HouseCompany extends Company {

    HouseCompany(Product product) {
        super(product);
    }

    @Override
    public void earnMoney() {
        super.earnMoney();
    }
}
/**
 * 汽车公司
 * @author test11
 */
public class CarCompany extends Company {

    CarCompany(Product product) {
        super(product);
    }

    @Override
    public void earnMoney() {
        super.earnMoney();
    }
}
/**
 * 综合业务
 * @author test11
 */
public class CombineCompany extends Company {


    CombineCompany(Product product) {
        super(product);
    }

    @Override
    public void earnMoney() {
        super.earnMoney();
    }
}

   测试不同公司赚钱方式

/**
 * 桥接模式测试类
 * @author test11
 */
public class Demo {

    public static void main(String[] args) {
        //房地产公司
        Company house = new HouseCompany(new House());
        house.earnMoney();

        //智能汽车
        Company car = new CarCompany(new Car());
        car.earnMoney();

        //综合业务
        Company cloth = new CombineCompany(new Cloth());
        cloth.earnMoney();

        Company drink = new CombineCompany(new Drink());
        drink.earnMoney();
    }
}

 

以上是关于桥接模式的主要内容,如果未能解决你的问题,请参考以下文章

桥接模式 C++ 代码编译错误

案例分析:设计模式与代码的结构特性

桥接模式-代码实现

23种设计模式之桥接模式代码实例

设计模式之桥接模式

桥接模式