桥梁模式

一)故事

二)定义
将抽象和实现解耦,使得两者可以独立地变化。

三)代码例子
共计四个类:1)实现化角色;2)具体实现化角色(可多个);3)抽象化角色;4)具体抽象化角色(可多个);
1)实现化角色
/**
 *  实现化角色(产品类)
 *
 * @author levovo
 */
public abstract class AbsProduct {
    public abstract void method1();
    public abstract void method2();
}

2)具体实现化角色(可多个)
/**
 *  具体实现化角色1(产品类1)
 *
 * @author levovo
 */
public class ConcreteProduct1 extends AbsProduct {
    
    @Override
    public void method1() {
        System.out.println("ConcreteProduct1()->method1()");
    }
    
    @Override
    public void method2() {
        // 业务逻辑处理
        System.out.println("ConcreteProduct1()->method2()");
    }
}

/**
 *  具体实现化角色2(产品类2)
 *
 * @author levovo
 */
public class ConcreteProduct2 extends AbsProduct {
    
    @Override
    public void method1() {
        System.out.println("ConcreteProduct2()->method1()");
    }
    
    @Override
    public void method2() {
        // 业务逻辑处理
        System.out.println("ConcreteProduct2()->method2()");
    }
}

3)抽象化角色
/**
 *  抽象化角色(公司类)
 *
 * @author levovo
 */
public abstract class AbsCorp {
    
    protected AbsProduct product = null;
    
    public AbsCorp(AbsProduct product) {
        this.product = product;
    }
    
    // 产品类的公共方法
    public void method1() {
        System.out.println("AbsCorp()->method1()");
        this.product.method1();
        this.product.method2();
    }
    // 抽象方法
    public abstract void method2();
}

4)具体抽象化角色(可多个)
/**
 * 具体抽象化角色1(公司类1)
 *
 * @author levovo
 */
public class Corp1 extends AbsCorp {
    
    public Corp1(AbsProduct product) {
        super(product);
    }
    
    @Override
    public void method2() {
        System.out.println("Corp1()->method2()");
    }
    
}

/**
 * 具体抽象化角色2(公司类2)
 *
 * @author levovo
 */
public class Corp2 extends AbsCorp {
    
    public Corp2(AbsProduct product) {
        super(product);
    }
    
    @Override
    public void method2() {
        System.out.println("Corp2()->method2()");
    }
    
}

场景使用例子:
/**
 *  场景使用例子
 *
 * @author levovo
 */
public class Client {
    public static void main(String[] args) {
        // 产品
        AbsProduct product = new ConcreteProduct1();
        // AbsProduct product = new ConcreteProduct2();
        // 公司,因公司不知道将来要生产什么样的产品,所以将产品放出去,
        // 通过构造函数或者setter注入进来,那么在Corp类就可以使用Product的方法了。
        AbsCorp corp = new Corp1(product);
        // AbsCorp corp = new Corp2(product);
        corp.method1();
        corp.method2();
    }
}

1)增加公司,要么继承Corp类,要么继承HouseCorp或ShanZhaiCorp,不用再修改原有的类了。
2)增加产品,继承Product类,或者继承House类,你要把房子分为公寓房,别墅,商业用房等。
你唯一要修改的就是Client类。类都增加了,高层模式也需要修改,也就是说Corp类和Product类都可以自由地扩展,而不会对整个应用产生太大的变更,这就是桥梁模式。

四)优点
1)抽象与实现分离
这也是桥梁模式的主要特点,它完全是为了解决继承的缺点而提出的设计模式,在该模式下,实现可以不受抽象的约束,不用再绑定在一个固定的抽象层次上。
2)优秀的扩充能力
看看我们的例子,想增加实现?没问题!想增加抽象,也没有问题!只要对外暴露的接口层允许这样的变化,我们已经把变化的可能性减到最小。
3)实现细节对客户透明
客户不用关心细节的实现,它已经由抽象层通过聚合关系完成了封装。

五)缺点

六)使用场景
1)不希望或不适用使用继承的场景
例如继承层次过渡,无法更细化设计颗粒等场景,需要考虑使用桥梁模式。
2)接口或抽象类不稳定的场景
明知道接口不稳定还想通过实现或继承来实现业务需求,那是得不偿失的,也是比较失败的做法。
3)重用性要求较高的场景
设计的颗粒度超细,则被重用的可能性就越大,而采用继承则受父类的限制,不可能出现太细的颗粒度。

七)注意事项
桥梁模式的意图还是对变化的封装,尽量把可能变化的因素封装到最、最小的逻辑单元中,避免风险扩散。如果在进行系统设计时,发现类的继承有N层时,可以考虑使用桥梁模式。

八)扩展

九)总结
我们来看看Corp生产Product的例子,因为Corp公司有可能生产不一样的产品Product,就是因为不知道将来要生产什么样的产品,所以把产品放出去(变成抽象类或者接口类),通过setter或者构造函数把产品Product类注入进来。
这种有两个好处:1)Corp类和Product类可以独立变化,就是解耦;2)Corp类把变化方法的放出去了,这样不会对Corp类产生影响;

如:Father类 -> Son类(Father子类) -> GrandSom类(Son子类)
桥梁模式描述了类间弱关联关系,Father类完全可以把可能会变化的方法放出去,Son子类要拥有这个方法很简单,桥梁搭过去,获得这个方法,GrandSon也一样,即使你Son子类不想使用这个方法也没关系,对GrandSon不产生影响,它不是从Son中继承来的方法。

对于比较明确不发生变化的,则通过继承来完成;若不能确定是否会发生变化的,那就认为是会发生变化, 则通过桥梁模式来解决。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值