这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被构造化改变而互不影响。
意图
可以将抽象化部分与实现化部分分开,取消二者的继续关系,改用组合关系。
办理问题
通过组合的办法办理多继续违背类的单一原则问题。
UML图
该模式中包含的角色及其职责
抽象化(Abstraction)
定义抽象类,并包含一个对实现化工具的引用,布局方法规定子类须要传入一个实现工具(Implementor)。该类常日定义为一个抽象类。
扩展抽象化(RefinedAbstraction)
是抽象化角色(Abstraction)的子类,实现并完善父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
实现化(Implementor)
定义实现化角色的接口,供扩展抽象化角色调用,定义实现维度的基本操作,供应给抽象化(Abstraction)利用。该类常日定义为一个接口或者抽象类。
详细实现化(ConcreteImplementor)
实现化角色接口(Implementor)的详细实现。
在本例子中:
优缺陷
优点
分离抽象接口及实在现部分。桥接模式有时类似于多继续方案,但是多继续方案违背了类的单一职责原则(即一个类只有一个变革的缘故原由),复用性比较差,而且多继续构造中类的个数非常弘大,桥接模式是比多继续方案更好的办理方法。桥接模式提高了系统的可扩充性,在两个变革维度中任意扩展一个维度,都不须要修正原有系统。实现细节对客户透明,可以对用户隐蔽实现细节。缺陷
桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,哀求开拓者针对抽象进运用处景如果一个别系须要在构件的抽象化角色和详细化角色之间增加更多的灵巧性,避免在两个层次之间建立静态的继续联系,通过桥接模式可以使它们在抽象层建立一个关联关系。一个类存在两个独立变革的维度,且这两个维度都须要进行扩展。虽然在系统中利用继续是没有问题的,但是由于抽象化角色和详细化角色须要独立变革,设计哀求须要独立管理这两者。对付那些不肯望利用继续或由于多层次继续导致系统类的个数急剧增加的系统,桥接模式尤为适用。接口或抽象类不稳定的场景案例背景举一个例子:一家汽车品牌的车常日都是会有多款车型和多款颜色,这里车型和颜色便是两个不同的详细实现,例如宝马3系可以有蓝色和赤色,宝马5系一样可以有蓝色跟赤色。当然实现方法可以有多种。
每一种车型针对不同的颜色创建不同的类,如 BMW3Read 和 BMW3Blue;BMW5Read 和 BMW5Blue。如果一天添加一个7系呢?BMW7Read 和 BMW7Blue,还是要这样写。根据车型和颜色组合实现,如:BMW3($red) 和 BMW3($blue);BMW5($red) 和 BMW5($blue)。添加7系也只须要 BMW7($red) 和 BMW7($blue) 就好了。两种办法可以进行比拟一下,第一种办法每款车型的颜色都须要详细的一个类实现,车型里面的内容无法复用,BMW3Read和BMW3Blue都须要重写一遍。细心的同学已经看到了可以通过继续实现对吧。
把公共的方法抽离出来放到 BMW3 这个类中,然后 BMW3Read 和 BMW3Blue 都去继续,这样的确可以实现。但是PHP和JAVA等措辞都是单继续的,如果须要继续 BMW 这个品牌呢?怎么办?
这时候我们可以采取第二种办法来实现,通过组合的办法,这样就可以用办理这个单继续的问题了。
示例代码
CarAbstraction.php 汽车抽象,抽象化(Abstraction)
interface CarAbstraction{ public function __construct(ColorImplementor $implementor); public function getCar();}
ColorImplementor.php 颜色实现,实现化(Implementor)
interface ColorImplementor{ public function getColor();}
BMW3RefinedAbstraction.php 3系汽车详细实现,扩展抽象化(RefinedAbstraction)
class BMW3RefinedAbstraction implements CarAbstraction{ private $implementor; public function __construct(ColorImplementor $implementor){ $this->implementor = $implementor; } public function getCar(){ return sprintf("%s----%s",$this->implementor->getColor(),"宝马3系"); }}
BMW5RefinedAbstraction.php 5系汽车详细实现,扩展抽象(RefinedAbstraction)
class BMW5RefinedAbstraction implements CarAbstraction{ private $implementor; public function __construct(ColorImplementor $implementor){ $this->implementor = $implementor; } public function getCar(){ return sprintf("%s----%s",$this->implementor->getColor(),"宝马5系"); }}
RedConcreteImplementor.php 赤色实现,详细实现化(ConcreteImplementor)
class RedConcreteImplementor implements ColorImplementor{ public function getColor(){ return "赤色"; }}
BlueConcreteImplementor.php 蓝色实现,详细实现化(ConcreteImplementor)
class BlueConcreteImplementor implements ColorImplementor{ public function getColor(){ return "蓝色"; }}
调用代码:
$red = new RedConcreteImplementor();//创建赤色$blue = new BlueConcreteImplementor();//创建蓝色$bmw3Red = new BMW3RefinedAbstraction($red);//创建赤色宝马3系$bmw3Blue = new BMW3RefinedAbstraction($blue);//创建蓝色宝马3系$bmw5Red = new BMW5RefinedAbstraction($red);//创建赤色宝马5系$bmw5Blue = new BMW5RefinedAbstraction($blue);//创建蓝色宝马5系echo $bmw3Red->getCar() . "\n";echo $bmw3Blue->getCar() . "\n";echo $bmw5Red->getCar() . "\n";echo $bmw5Blue->getCar() . "\n";
输出结果:
赤色----宝马3系蓝色----宝马3系赤色----宝马5系蓝色----宝马5系
更多文章关注微信"大众年夜众号:IT不是挨踢
如果以为文章还不错,请把文章分享给更多的人学习,在文章中创造有误的地方也希望各位指出更正。现有误的地方也希望各位指出更正。