设计模式之禅-桥梁模式

桥梁模式

例子

加入自己有两家公司,一家房地产公司只生产房子,一家山寨公司什么都可以生产。
在这里插入图片描述

public abstract class Corp {
    private Product product;

    public Corp(Product product) {
        this.product = product;
    }

    public void makeMoney() {
        this.product.beProducted();
        this.product.beSelled();
    }
}
public abstract class Product {
    public abstract void beProducted();
    public abstract void beSelled();
}
public class HouseCorp extends Corp{

    public HouseCorp(House house) {
        super(house);
    }
    @Override
    public void makeMoney(){
        super.makeMoney();
        System.out.println("房地产公司赚大钱了...");
    }
}
public class ShanZhaiCorp extends Corp{
    public ShanZhaiCorp(Product product) {
        super(product);
    }
    @Override
    public void makeMoney(){
        super.makeMoney();
        System.out.println("我赚钱呀...");
    }
}
public class House extends Product{

    @Override
    public void beProducted() {
        System.out.println("生产出的房子是这样的...");
    }

    @Override
    public void beSelled() {
        System.out.println("生产出的房子卖出去了...");
    }
}
public class IPod extends Product{
    @Override
    public void beProducted() {
        System.out.println("生产出的iPod是这样的...");
    }

    @Override
    public void beSelled() {
        System.out.println("生产出的iPod卖出去了...");
    }
}
public class Cloth extends Product{

    @Override
    public void beProducted() {
        System.out.println("生产出的衣服是这样的...");
    }

    @Override
    public void beSelled() {
        System.out.println("生产出的衣服卖出去了...");
    }
}
public class Client {
    public static void main(String[] args) {
        House house = new House();
        System.out.println("-------房地产公司是这样运行的-------");
        HouseCorp houseCorp = new HouseCorp(house);
        houseCorp.makeMoney();
        System.out.println("-------山寨公司是这样运行的-------");
        ShanZhaiCorp shanZhaiCorp = new ShanZhaiCorp(new Cloth());
        shanZhaiCorp.makeMoney();
    }
}

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

既然万物都是运动的,我现在只有房地产公司和山寨公司,那以后我会不会增加一些 其他的公司呢?或者房地产公司会不会对业务进行细化,如分为公寓房公司、别墅公司,以及商业房公司等。

这种变化对我们上面 的类图来说不会做大的修改,充其量只是扩展:

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

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

定义

将抽象和实现解耦,使得两者可以独立地变化。
在这里插入图片描述

  • Abstraction——抽象化角色
    它的主要职责是定义出该角色的行为,同时保存一个对实现化角色的引用,该角色一般是抽象类。
  • Implementor——实现化角色
    它是接口或者抽象类,定义角色必需的行为和属性。
  • RefinedAbstraction——修正抽象化角色
    它引用实现化角色对抽象化角色进行修正。
  • ConcreteImplementor——具体实现化角色
    它实现接口或抽象类定义的方法和属性。
public interface Implementor {
    void doSomething();
    void doAnything();
}
public class ConcreteImplementor1 implements Implementor{

    @Override
    public void doSomething() {

    }

    @Override
    public void doAnything() {

    }
}
public class ConcreteImplementor2 implements Implementor{

    @Override
    public void doSomething() {
        
    }

    @Override
    public void doAnything() {

    }
}
public abstract class Abstraction {
    private Implementor imp;

    public Abstraction(Implementor imp) {
        this.imp = imp;
    }
    public void request(){
        this.imp.doSomething();
    }
    public Implementor getImp(){
        return this.imp;
    }
}
public class RefinedAbstraction extends Abstraction{
    public RefinedAbstraction(Implementor imp) {
        super(imp);
    }
    @Override
    public void request(){
        super.request();
        super.getImp().doAnything();
    }
}
public class Client {
    public static void main(String[] args) {
        ConcreteImplementor1 imp = new ConcreteImplementor1();
        RefinedAbstraction abs = new RefinedAbstraction(imp);
        abs.request();
    }
}

桥梁模式是一个非常简单的模式,它只是使用了类间的聚合关系、继承、覆写等常用功能,但是它却提供了一个非常清晰、稳定的架构。

优点

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

使用场景

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

注意

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值