2. 桥接模式(Bridge)
桥接模式是一种很有意思的模式,它的结构确实像一座桥一样,与桥相连的两端都可以各自独立的变化,让一组实现与另外一组使用它们的对象分离。我们可以举个例子来说明:
还是回到先前的方便面厂那个例子,还是要构建一个生产北京,杭州两种地方口味的方便面,同样是牛肉面也就有了北京口味的牛肉面和杭州口味的牛肉面,西红柿打卤面也分北京口味和杭州口味之分。这里为了便于理解,口味上这样区分,北京口味的盐稍微多些,有少许辣味;杭州口味的稍微少些,有少许甜味。
好了,开始实现这个整体结构吧。
首先是方便面工厂的抽象基类:
这里的Implementer就是InstantNoodleFactory使用的一组实现类的基接口,正是InstantNoodleFactory和Implementer实现了"桥接"。
下面看一下Implementer:
这个类负责实现不同地方口味的实现,我们来实现两个它的子类
这两个类分别实现了两种不同的地方口味。
最后来看看方便面抽象工厂的实现,它使用了Implementer类,并且它不去关心到底实现Implementer的是什么类
这样,通过这种结构,实现了牛肉面工厂与地方口味的解耦,只要更换了Implementer的实现,就可以在不同的地方口味中切换了。这样就大大的减少了类的数量,要生产带有地方口味的牛肉面也不用出现BeijingBeefInstantNoodleFactory,HangzhouBeefInstantNoodleFactory这样的类了。
最后是一个客户端:
桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。它的类图如下所示:
[img]http://zddava.iteye.com/upload/attachment/78394/babbaaa5-9754-3c3f-b69f-bda8d056556c.jpg[/img]
桥接模式可以用于当一个接口或抽象类的继承结构中出现了某些概念上的重复时,比如上面的例子中就出现了"北京口味牛肉面","杭州口味牛肉面"等等,这里就出现了"牛肉"这个概念的重复,这是就可以使用桥接模式来分拆接口了,分成抽象和实现两个部分。
桥接模式是一种很有意思的模式,它的结构确实像一座桥一样,与桥相连的两端都可以各自独立的变化,让一组实现与另外一组使用它们的对象分离。我们可以举个例子来说明:
还是回到先前的方便面厂那个例子,还是要构建一个生产北京,杭州两种地方口味的方便面,同样是牛肉面也就有了北京口味的牛肉面和杭州口味的牛肉面,西红柿打卤面也分北京口味和杭州口味之分。这里为了便于理解,口味上这样区分,北京口味的盐稍微多些,有少许辣味;杭州口味的稍微少些,有少许甜味。
好了,开始实现这个整体结构吧。
首先是方便面工厂的抽象基类:
// 这里和工厂模式没有关系哦
// 方便面工厂
public abstract class InstantNoodleFactory {
protected Implementer impl = null;
public void setImpl(Implementer impl) {
this.impl = impl;
}
public abstract void produce();
}
这里的Implementer就是InstantNoodleFactory使用的一组实现类的基接口,正是InstantNoodleFactory和Implementer实现了"桥接"。
下面看一下Implementer:
public interface Implementer {
// 加入地方特色的口味
public void addDistrictTaste();
}
这个类负责实现不同地方口味的实现,我们来实现两个它的子类
public class BeijingImplementer implements Implementer {
@Override
public void addDistrictTaste() {
System.out.println("加入稍多的盐");
System.out.println("加入微量辣味");
}
}
public class HangzhouImplementer implements Implementer {
@Override
public void addDistrictTaste() {
System.out.println("加入稍少的盐");
System.out.println("加入微量甜味");
}
}
这两个类分别实现了两种不同的地方口味。
最后来看看方便面抽象工厂的实现,它使用了Implementer类,并且它不去关心到底实现Implementer的是什么类
// 牛肉面工厂
public class BeefInstantNoodleFactory extends InstantNoodleFactory {
@Override
public void produce() {
prepare();
// 加入地方口味
this.impl.addDistrictTaste();
}
private void prepare() {
System.out.println("准备制作牛肉面");
}
}
这样,通过这种结构,实现了牛肉面工厂与地方口味的解耦,只要更换了Implementer的实现,就可以在不同的地方口味中切换了。这样就大大的减少了类的数量,要生产带有地方口味的牛肉面也不用出现BeijingBeefInstantNoodleFactory,HangzhouBeefInstantNoodleFactory这样的类了。
最后是一个客户端:
public class Client {
public static void main(String[] args) {
// 北京口味
Implementer impl = new BeijingImplementer();
// 制造牛肉面
InstantNoodleFactory fac = new BeefInstantNoodleFactory();
// 设定北京口味
fac.setImpl(impl);
// 生产
fac.produce();
// 杭州口味
impl = new HangzhouImplementer();
// 设定杭州口味
fac.setImpl(impl);
// 生产
fac.produce();
}
}
桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。它的类图如下所示:
[img]http://zddava.iteye.com/upload/attachment/78394/babbaaa5-9754-3c3f-b69f-bda8d056556c.jpg[/img]
桥接模式可以用于当一个接口或抽象类的继承结构中出现了某些概念上的重复时,比如上面的例子中就出现了"北京口味牛肉面","杭州口味牛肉面"等等,这里就出现了"牛肉"这个概念的重复,这是就可以使用桥接模式来分拆接口了,分成抽象和实现两个部分。