java设计模式---桥接模式(Bridge pattern)

java设计模式—桥接模式(Bridge pattern)

桥接模式是结构型设计模式之一,也称为桥梁模式。桥接模式(Bridge)是为了解决将抽象部分与实现部分分离,好让他们都在自己的维度上有多维度地变化。
1. 定义
将抽象部分(Abstraction)与实现部分(Implementor)分离,使它们可以独立地变化。从模式的定义上来看,我们可以知道,这里的桥梁指的就是连接抽象类与实现类之间的桥梁,使得他们就可以独立的变化而互不影响。
一个简单的场景:
毛笔和蜡笔。假如我们需要大中小 3 种型号的画笔,能够绘制 12 种不同的颜色,如果使用蜡笔,需要准备 3×12 = 36 支,但如果使用毛笔的话,只需要提供 3 种型号的毛笔,外加 12 个颜料盒即可,涉及到的对象个数仅为 3 + 12 = 15,远小于36,却能实现与 36 支蜡笔同样的功能。如果增加一种新型号的画笔,并且也需要具有 12 种颜色,对应的蜡笔需增加 12 支,而毛笔只需增加一支。为什么会这样呢?通过分析我们可以得知:在蜡笔中,颜色和型号两个不同的变化维度(即两个不同的变化原因)融合在一起,无论是对颜色进行扩展还是对型号进行扩展都势必会影响另一个维度;但在毛笔中,颜色和型号实现了分离,增加新的颜色或者型号对另一方都没有任何影响。如果使用软件工程中的术语,我们可以认为在蜡笔中颜色和型号之间存在较强的耦合性,而毛笔很好地将二者解耦,使用起来非常灵活,扩展也更为方便
2. UML图
首先看下桥接模式结构图,如下:
这里写图片描述
在上图结构图中包含如下几个角色:
Abstraction(抽象类):用于定义抽象类的接口,它一般是抽象类而不是接口,其中定义了一个 Implementor(实现类接口)类型的对象并可以维护该对象,它与 Implementor 之间具有关联关系,它既可以包含抽象业务方法,也可以包含具体业务方法。
RefinedAbstraction(扩充抽象类):扩充由 Abstraction 定义的接口,通常情况下它不再是抽象类而是具体类,它实现了在 Abstraction 中声明的抽象业务方法,在 RefinedAbstraction 中可以调用在 Implementor 中定义的业务方法。
Implementor(实现类接口):定义实现类的接口,这个接口不一定要与 Abstraction 的接口完全一致,事实上这两个接口可以完全不同,一般而言,Implementor 接口仅提供基本操作,而 Abstraction 定义的接口可能会做更多更复杂的操作。Implementor 接口对这些基本操作进行了声明,而具体实现交给其子类。通过关联关系,在 Abstraction 中不仅拥有自己的方法,还可以调用到 Implementor 中定义的方法,使用关联关系来替代继承关系。
ConcreteImplementor(具体实现类):具体实现 Implementor 接口,在不同的 ConcreteImplementor 中提供基本操作的不同实现,在程序运行时,ConcreteImplementor 对象将替换其父类对象,提供给抽象类具体的业务操作方法。
桥接模式是一个非常有用的模式,在桥接模式中体现了很多面向对象设计原则的思想,包括“单一职责原则”、“开闭原则”、“合成复用原则”、“里氏代换原则”、“依赖倒转原则”等。熟悉桥接模式有助于我们深入理解这些设计原则,也有助于我们形成正确的设计思想和培养良好的设计风格。
3. 示例
我们继续举毛笔和蜡笔的例子,并以简单的代码实现,首先看下结构图,如下所示:
这里写图片描述
结合上图的结构图,如果我们要增加一种毛笔类型的话只需要修改左边的抽象部分,下面添加一个新的毛笔类型。如果需要增加一种新的颜色,只需扩展右侧的实现部分,增加一个新的具体实现类。扩展非常方便,无须修改已有代码,且不会导致类的数目增长过快
在具体编码实现时,由于在桥接模式中存在两个独立变化的维度,为了使两者之间耦合度降低,首先需要针对两个不同的维度提取抽象类和实现类接口,并建立一个抽象关联关系。对于实现部分维度,典型的实现类接口代码如下所示:

interface Implementor {  
    public void operationImpl();  
}   

在实现 Implementor 接口的子类中实现了在该接口中声明的方法,用于定义与该维度相对应的一些具体方法。
对于另一抽象部分维度而言,其典型的抽象类代码如下所示:

abstract class Abstraction {  
    protected Implementor impl; //定义实现类接口对象  
    public void setImpl(Implementor impl) {  
        this.impl=impl;  
    }  

    public abstract void operation();  //声明抽象业务方法  
}   

在抽象类 Abstraction 中定义了一个实现类接口类型的成员对象 impl,再通过注入的方式给该对象赋值,一般将该对象的可见性定义为 protected,以便在其子类中访问 Implementor 的方法,其子类一般称为扩充抽象类或细化抽象类(RefinedAbstraction),典型的 RefinedAbstraction 类代码如下所示:

class RefinedAbstraction extends Abstraction {  
    public void operation() {  
        //业务代码  
        impl.operationImpl();  //调用实现类的方法  
        //业务代码  
    }  
}   

对于客户端而言,可以针对两个维度的抽象层编程,在程序运行时再动态确定两个维度的子类,动态组合对象,将两个独立变化的维度完全解耦,以便能够灵活地扩充任一维度而对另一维度不造成任何影响。

//定义毛笔抽象类
public abstract class InkBrush {
    Color color;
    public void setColor(Color color) {
        this.color = color;
    }
    abstract void write();
}
//定义颜色抽象类
public abstract class Color {
    abstract String draw();
}
//定义具体的颜色
public class Blue extends Color {
    @Override
    String draw() {
        System.out.println("draw blue color");
        return "blue";
    }
}
public class Red extends Color {
    @Override
    String draw() {
        System.out.println("draw red color");
        return "red";
    }
}
//定义具体的毛笔
public class SmallInkBrush extends InkBrush {
    @Override
    void write() {
        System.out.println("small ink brush write color :"+ color.draw());
    }
}
public class LargeInkBrush extends InkBrush {
    @Override
    void write() {
        System.out.println("large ink brush write color :"+ color.draw());
    }
}
//测试类
public class Test {
    public static void main(String[] args) {
        Red red = new Red();
        Blue blue = new Blue();

        LargeInkBrush largeInkBrush = new LargeInkBrush();
        largeInkBrush.setColor(red);
        largeInkBrush.write();
        largeInkBrush.setColor(blue);
        largeInkBrush.write();

        SmallInkBrush smallInkBrush = new SmallInkBrush();
        smallInkBrush.setColor(blue);
        smallInkBrush.write();
        smallInkBrush.setColor(red);
        smallInkBrush.write();
    }
}

4. 桥接模式与装饰者模式的区别
桥接模式的定义是将抽象化与实现化分离(用组合的方式而不是继承的方式),使得两者可以独立变化。可以减少派生类的增长。这样看起来和装饰者差不多,但两者还是有一些比较重要的区别:
(1)桥接模式中所说的分离,其实是指将结构与实现分离(当结构和实现有可能发生变化时)或属性与基于属性的行为进行分离;而装饰者只是对基于属性的行为进行封闭成独立的类。
(2)桥接中的行为是横向的行为,行为彼此之间无关联;而装饰者模式中的行为具有可叠加性,其表现出来的结果是一个整体,一个各个行为组合后的一个结果。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java设计模式是一组经过实践验证的面向对象设计原则和模式,可以帮助开发人员解决常见的软件设计问题。下面是常见的23种设计模式: 1. 创建型模式(Creational Patterns): - 工厂方法模式(Factory Method Pattern) - 抽象工厂模式(Abstract Factory Pattern) - 单例模式(Singleton Pattern) - 原型模式(Prototype Pattern) - 建造者模式(Builder Pattern) 2. 结构型模式(Structural Patterns): - 适配器模式(Adapter Pattern) - 桥接模式Bridge Pattern) - 组合模式(Composite Pattern) - 装饰器模式(Decorator Pattern) - 外观模式(Facade Pattern) - 享元模式(Flyweight Pattern) - 代理模式(Proxy Pattern) 3. 行为型模式(Behavioral Patterns): - 责任链模式(Chain of Responsibility Pattern) - 命令模式(Command Pattern) - 解释器模式(Interpreter Pattern) - 迭代器模式(Iterator Pattern) - 中介者模式(Mediator Pattern) - 备忘录模式(Memento Pattern) - 观察者模式(Observer Pattern) - 状态模式(State Pattern) - 策略模式(Strategy Pattern) - 模板方法模式(Template Method Pattern) - 访问者模式(Visitor Pattern) 4. 并发型模式(Concurrency Patterns): - 保护性暂停模式(Guarded Suspension Pattern) - 生产者-消费者模式(Producer-Consumer Pattern) - 读写锁模式(Read-Write Lock Pattern) - 信号量模式(Semaphore Pattern) - 线程池模式(Thread Pool Pattern) 这些设计模式可以根据问题的特点和需求来选择使用,它们提供了一些可复用的解决方案,有助于开发高质量、可维护且易于扩展的软件系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值