桥接模式
桥接模式(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(); } }