桥接模式 bridge pattern
一 定义
桥接模式,是将抽象部分与它的具体实现部分分离,使它们都可以独立地变化。它是将两个不同的维度建立联系。这两个维度通常是指:抽象维度和实现维度。
使用场景
- 在抽象和具体实现之间需要增加更多的灵活性的场景。
- 一个类存在两个(或多个)独立变化的维度,而这两个(或多个)维度都需要独立进行扩展。
- 不希望使用继承,尤其是多层继承。
标准示例
如类图所示:
Abstraction
和 RefinedAbstraction
是抽象维度体系;
Iimplementor
和 ConcreteImplementorA
ConcreteImplementorB
是实现维度体系;
Abstraction
作为桥梁,将抽象维度和实现维度进行了连接。
更多示例
接下来我们来举两个例子说明桥接模式的使用。
第一个例子是 快餐店。
众所周知,比较知名的几个洋快餐有:肯德基、麦当劳、汉堡王。
他们都属于快餐品牌。所以我们创建一个快餐店的抽象类:FastRestaurant。
然后让 KFCRestaurant、McRestraurant、BkRestraurant继承FastRestaurant。
各个快餐店都有自己的薯条和可乐。
接下来,我们做三件事情:
第一件事情:
所以我们创建薯条接口(Frenchfries)和可乐接口(Cola),
薯条接口里有个吃薯条的方法;可乐接口里有个喝可乐的方法。
//薯条接口
public interface Frenchfries {
//吃薯条
void eatFrenchfries();
}
//可乐接口
public interface Cola {
//喝可乐
void drinkCola();
}
第二件事情:
我们给FastRestaurant
① 增加两个属性,可乐和薯条。
② 增加两个方法:喝可乐(getCola)、吃薯条(getFrenchfries)。
//快餐店(抽象类)
public abstract class FastRestaurant {
//可乐
protected Cola cola;
//薯条
protected Frenchfries frenchfries;
//构造函数给属性赋值
public FastRestaurant(Cola cola,Frenchfries frenchfries){
this.cola = cola;
this.frenchfries = frenchfries;
}
//喝可乐
public void drinkCola(){
this.cola.drinkCola();
}
//吃薯条
public void eatFrenchfries(){
this.frenchfries.eatFrenchfries();
}
}
第三件事情:
然后让三家品牌都继承抽象类FastRestaurant。
BkCola、BkFrenchfries
KfcCola、KfcFrenchfries
McCola、McFrenchfries
//KFC (其他两个类似)
public class KfcRestaurant extends FastRestaurant{
public KfcRestaurant(Cola cola, Frenchfries frenchfries) {
super(cola, frenchfries);
}
}
接下来,我们要去KFC吃汉堡和可乐:
public class MainTest {
public static void main(String[] args) {
Cola cola = new KfcCola();
Frenchfries frenchfries = new KfcFrenchfries();
FastRestaurant restaurant = new KfcRestaurant(cola,frenchfries);
restaurant.drinkCola();
restaurant.eatFrenchfries();
}
}
执行后的输出结果:
Drink KFC's cola.
Eat KFC's French fries.
上述洋快餐的例子中,抽象的快餐店(FastRestaurant)充当了桥梁,连接了具体的快餐店(fcRestaurant)和 Cola、Frenchfries接口的实现(KfcCola、KfcFrenchfries)
我们来看类图:
我们再举个例子。
我们在购物时,经常有各种优惠活动。
比如满100减10,就是满金额直减;比如满200打8折,就是满金额折扣;比如满10件打9折,就是满数量折扣。
不难发现,就上述三种优惠来说,它是由条件规则+优惠 组成的。
我们把“满100”称为 rule,把“减10”称为 promotion。
下面来讲我们如何实现这些优惠。
首先我们定义一个抽象的条件规则类:AbstractRule
//抽象规则类
public abstract class AbstractRule {
//优惠
protected IPromotion promotion;
//规则名称
protected String rule;
//通过构造方法赋值
public AbstractRule(IPromotion promotion,String rule){
this.rule = rule;
this.promotion = promotion;
}
//获取优惠
public void getPromo(){
this.promotion.getPromotion(rule);
}
}
接下来,我们定义优惠接口。
//优惠接口
public interface IPromotion {
//获取优惠
void getPromotion(String rule);
}
然后给出具体的条件规则:满金额的规则和满数量的规则。
//满金额规则类
public class FullAmountRule extends AbstractRule{
public FullAmountRule(IPromotion promotion,String rule) {
super(promotion,rule);
}
}
//满数量规则类
public class FullQuantityRule extends AbstractRule{
public FullQuantityRule(IPromotion promotion,String rule) {
super(promotion,rule);
}
}
紧接着是要给出优惠接口的实现:直减优惠和折扣优惠。
public class DirectAmount implements IPromotion{
@Override
public void getPromotion(String rule) {
System.out.println(rule + " direct reduce amount");
}
}
public class Discount implements IPromotion{
@Override
public void getPromotion(String rule) {
System.out.println(rule + " discount.");
}
}
最后,我们来看一下这个优惠规则的实际使用效果:
public class MainTest {
public static void main(String[] args) {
//满金额
String rule = "Full amount";
//直减
IPromotion promotion = new Discount();
//优惠
AbstractRule theRule = new FullAmountRule(promotion,rule);
theRule.getPromo();
}
}
执行后的输出结果:
Full amount discount.
同样给出类图,发现与上面的图很相似(这就是桥接的模样):
以上就是桥接模式的全部内容,欢迎阅读。