桥梁模式
前言
桥接模式核心要点:
处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立
的继承结构,使各个维度可以独立的扩展在抽象层建立关联
一、场景
商城系统中常见的商品分类,以电脑为类,如何处理商品的分类?
可以用多层继承结构实现:
问题:
扩展性问题(类个数膨胀问题):
如果要增加一个新的电脑类型:智能手机,则要增加各个品牌下面的类。如果要增加一个新的品牌,也要增加各种电脑类型的类。
违反单一职责原则∶
一个类:联想笔记本,有两个引起这个类变化的原因
二、具体实现
以OA系统中的消息处理的实际情况为例,业务类型包含:普通消息、加急消息、特急消息;发送消息方式包含:站内消息、手机消息、邮件。这是两个维度,当一个维度发生变化时,肯定会引起另一个维度的变化,所以为了程序的扩展性,需要将两个维度分开。
1.实现代码
(1)定义发送消息的接口
/**
* 实现发送消息的接口
*/
public interface MessageImplementor {
/**
* 发送消息
* @param message
* @param toUser
*/
public void send(String message , String toUser);
}
(2)定义抽象的消息对象
/**
* 抽象的消息对象
*/
public class AbstractMessage {
/**
* 持有一个实现部分的对象
*/
protected MessageImplementor impl;
/**
* 构造方法,传入实现的对象
* @param impl
*/
public AbstractMessage(MessageImplementor impl) {
this.impl = impl;
}
/**
* 发送消息,转调实现部分的方法
* @param message
* @param toUser
*/
public void sendMessage (String message , String toUser){
this.impl.send(message,toUser);
}
}
(3)站内短消息的实现
/**
* 以站内短消息的方式发送消息
*/
public class MessageSMS implements MessageImplementor{
@Override
public void send(String message, String toUser) {
System.out.println("以站内短消息的方式,发送消息"+message+"给"+toUser);
}
}
(4)Email方式的实现
/**
* 以Email方式发送消息
*/
public class MessageEmail implements MessageImplementor{
@Override
public void send(String message, String toUser) {
System.out.println("使用Email的方式,发送消息"+message+"给"+toUser);
}
}
(5)普通消息的实现
/**
* 普通消息
*/
public class CommonMessage extends AbstractMessage{
/**
* 构造方法,传入实现的对象
*
* @param impl
*/
public CommonMessage(MessageImplementor impl) {
super(impl);
}
public void sendMessage(String message , String toUser){
//普通消息,直接调用父类方法
super.sendMessage(message,toUser);
}
}
(6)加急消息的实现
/**
* 加急消息
*/
public class UrgencyMessage extends AbstractMessage{
/**
* 构造方法,传入实现的对象
*
* @param impl
*/
public UrgencyMessage(MessageImplementor impl) {
super(impl);
}
public void sendMessage(String message , String toUser){
message = "加急"+message;
super.sendMessage(message,toUser);
}
/**
* 扩展自己的新功能:监控处理某消息的处理过程
* @param messageId
* @return
*/
public Object watch(String messageId){
return null;
}
}
2.扩展代码
(7)特急消息的实现
public class SpecialUrgencyMessage extends AbstractMessage {
/**
* 构造方法,传入实现的对象
*
* @param impl
*/
public SpecialUrgencyMessage(MessageImplementor impl) {
super(impl);
}
public void hurry(String messageId){
//执行催促的业务
}
public void sendMessage(String message,String toUser){
message = "特急"+message;
super.sendMessage(message,toUser);
}
}
(8)手机短消息的实现
/**
* 以手机短消息的方式发送消息
*/
public class MessageMobile implements MessageImplementor{
@Override
public void send(String message, String toUser) {
System.out.println("使用手机短消息的方式,发送消息"+message+"给"+toUser);
}
}
3.测试代码
/**
* 客户端测试类
*/
public class Client {
public static void main(String[] args) {
//创建具体的实现对象
MessageImplementor impl = new MessageSMS();
//创建一个普通消息对象
AbstractMessage m =new CommonMessage(impl);
m.sendMessage("请喝杯茶!","小李");
//创建一个紧急消息对象
m = new UrgencyMessage(impl);
m.sendMessage("请喝杯茶!","小李");
//创建一个特急对象
m = new SpecialUrgencyMessage(impl);
m.sendMessage("请喝杯茶!","小李");
//切换成手机短消息
impl = new MessageMobile();
m = new CommonMessage(impl);
m.sendMessage("请喝杯茶!","小李");
m = new UrgencyMessage(impl);
m.sendMessage("请喝杯茶!","小李");
m = new SpecialUrgencyMessage(impl);
m.sendMessage("请喝杯茶!","小李");
}
}
结果:
三、应用场景
– JDBC驱动程序
– AWT中的Peer架构
– 银行日志管理:
• 格式分类:操作日志、交易日志、异常日志
• 距离分类:本地记录日志、异地记录日志
– 人力资源系统中的奖金计算模块:
• 奖金分类:个人奖金、团体奖金、激励奖金。
• 部门分类:人事部门、销售部门、研发部门。
– OA系统中的消息处理:
• 业务类型:普通消息、加急消息、特急消息
• 发送消息方式:系统内消息、手机短信、邮件
总结
- 桥接模式可以取代多层继承的方案。 多层继承违背了单一职责原则,复用性较差,类的个数也非常多。桥接模式可以极大的减少子类的个数,从而降低管理和维护的成本。
- 桥接模式极大的提高了系统可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有的系统,符合开闭原则