桥接模式
将抽象和实现解耦,使得两者可以独立地变化
桥梁模式虽然不是一个使用频率很高的模式,但是熟悉这个模式对于理解面向对象的设计原则,包括“开-闭”原则以及组合/聚合复用原则都很有帮助。理解好这两个原则,有助于形成正确的设计思想和培养良好的设计风格。
桥梁模式角色
- 抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用;
- 修正抽象化(RefinedAbstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义;
- 实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个 接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出 底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作;
- 具体实现化(ConcreteImplementor)角色:这个角色给出实现化角色接口的具体实现。
桥接模式的优点
- 抽象和实现分离是桥梁的主要特点,是为了解决继承的缺点而提出的设计模式。在该模式下,
- 实现可以不受抽象的约束,不用绑定在一个固定的抽象层次上;
- 实现对客户透明,客户端不用关心细节的实现,它已经有抽象层通过聚合关系完成了封装;
- 提高灵活性和扩展性。
使用场景
- 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系;
- 设计要求实现化角色的任何改变不影响客户端,或者说实现化角色的改变对客户端是完全透明的;
- 一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合;
- 不希望或不适合使用继承的场合。继承具有很强的侵入性质,即父类有的方法,子类必须有;而桥接模式是弱关联关系。因此对于比较明确不发生变化的,则可以通过继承完成;若不能确定是否会发生变化,则通过桥梁模式来解决。
<span style="font-size:18px;">package bridgemodel;
/**
* 发送消息统一接口
*
*/
public interface MessageImplementor {
/**
* 发送消息方法
* @param message 消息内容
* @param sender 发送者
* @param receiver 接手者
*/
public void send(String message,String sender,String receiver);
}
</span>
<span style="font-size:18px;">package bridgemodel;
/**
*消息发送执行类,实现消息发送执行接口,使用短信发送方式
*
*/
public class MessageSMS implements MessageImplementor {
public void send(String message, String sender, String receiver) {
// TODO Auto-generated method stub
System.out.println("使用短信发送方式发送消息,消息内容: "+message+"\n发送者: "+sender+"\n接收者: "+receiver);
}
}
</span>
<span style="font-size:18px;">package bridgemodel;
/**
*消息发送执行类,实现消息发送执行接口,使用邮件发送方式
*
*/
public class MessageEmail implements MessageImplementor {
public void send(String message, String sender, String receiver) {
// TODO Auto-generated method stub
System.out.println("使用邮件发送方式发送消息,消息内容: "+message+"\n发送者: "+sender+"\n接收者: "+receiver);
}
}
</span>
<span style="font-size:18px;">package bridgemodel;
/**
* 抽象消息类
*
*/
public abstract class AbstractMessage {
//持有一个实现部分的对象
MessageImplementor impl;
/**
* 构造方法,传入实现部分的对象
* @param impl 实现部分的对象
*/
public AbstractMessage(MessageImplementor impl){
this.impl = impl;
}
/**
* 发送消息,委派给实现部分的方法
* @param message
* @param sender
* @param receiver
*/
public void sendMessage(String message , String sender,String receiver){
this.impl.send(message, sender,receiver);
}
}
</span>
<span style="font-size:18px;">package bridgemodel;
/**
* 普通消息
*
*/
public class CommonMessage extends AbstractMessage {
public CommonMessage(MessageImplementor impl) {
super(impl);
}
@Override
public void sendMessage(String message, String sender,String receiver) {
// 对于普通消息,直接调用父类方法,发送消息即可
super.sendMessage(message, sender,receiver);
}
}
</span>
<span style="font-size:18px;">package bridgemodel;
/**
* 加急送
*
*/
public class UrgencyMessage extends AbstractMessage {
public UrgencyMessage(MessageImplementor impl) {
super(impl);
}
@Override
public void sendMessage(String message, String sender,String receiver) {
message = "加急:" + message;
super.sendMessage(message, sender,receiver);
}
}</span>
<span style="font-size:18px;">package bridgemodel;
public class Client {
public static void main(String[] args) {
//创建具体的实现对象
MessageImplementor impl = new MessageSMS();
//创建普通消息对象
AbstractMessage message = new CommonMessage(impl);
message.sendMessage("加班申请速批","张三","林经理");
//将实现方式切换成邮件,再次发送
impl = new MessageEmail();
//创建加急消息对象
message = new UrgencyMessage(impl);
message.sendMessage("加班申请速批","张三","林经理");
}
}
</span>