桥接模式 - Bridge Pattern
定义
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
设计的原则和思想
- 解耦的是抽象部分和实现的部分。
- 不变部分是抽象部分,变化部分是实现部分。
- 核心思想是通过组合的方式,让类的个数从指数增长下降到线性增长。
一句话概括设计模式
一个类存在多个独立变化的维度,通过组合的方式,让多个维度可以独立地变化。
经典版本
结构中包含的角色
- Abstraction(抽象类)
- RefinedAbstraction(扩充抽象类)
- Implementor(实现类接口)
- ConcreteImplementor(具体实现类)
最小可表达代码
interface Implementor {}
abstract class Abstraction
{
protected $impl;
public function __construct(Implementor $impl)
{
$this->impl = $impl;
}
public abstract function hand();
}
class ConcreteImplementor implements Implementor{}
class RefinedAbstraction extends Abstraction
{
public function hand()
{
echo '执行';
}
}
$impl = new ConcreteImplementor();
$abstraction = new RefinedAbstraction($impl);
$abstraction->hand();
JDBC版本
结构中包含的角色
- Driver(抽象类)
- ConcreteDriver(具体抽象类)
- Connection(实现类接口)
- ConcreteConnection(具体实现类)
- DriverManager (桥接类) 连接两个变化维度的中间类
最小可表达代码
interface Driver{}
class ConcreteDriver implements Driver{}
interface Connection{}
class ConcreteConnection implements Connection{}
class DriverManager
{
protected $driver;
protected $connection;
public function __construct(Driver $driver, Connection $connection)
{
$this->driver = $driver;
$this->connection = $connection;
}
public function hand()
{
echo '执行';
}
}
$manager = new DriverManager(new ConcreteDriver, new ConcreteConnection);
$manager->hand();
优点
- 抽象和实现的分离,并且互不相互影响。
- 用一种巧妙的方式处理多层继承存在的问题,用抽象关联取代了传统的多层继承,将类之间的静态继承关系转换为动态的对象组合关系。
缺点
- 增加系统的理解与设计难度。
- 要求针对抽象设计和编程,代码更加复杂。
何时使用
- 一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展。
- 需要解决继承导致系统类的个数急剧增加的问题。
- 系统需要对抽象化角色和实现化角色进行动态切换。
- 想要拆分或重组一个具有多重功能的庞杂类 (与多个数据库服务器进行交互的类)。
实际应用场景
- 商城笔记本的型号和品牌
- JDBC
为什么叫桥接模式
类似一条连接两个独立变化维度的桥接。
抽象和实现是什么意思?
抽象 :
不是抽象类或者接口。而是跟具体的数据库无关的、被抽象出来的一套类库,例如JDBC。
实现 :
不是接口的实现类。而是跟具体数据库相关的一套类库,比如,com.mysql.jdbc.Driver。
怎样识别一个类中所具有的独立变化维度。
抽象类 : 与业务方法关系最密切的维度。
实现类 : 另一个维度。