桥接模式(bridge)
介绍
-
场景
- 商城系统中常见的商品分类,以电脑为类,如何良好的处理商品分类销售的问题呢?
-
我们可以用多层继承结构实现如图关系
-
问题:
-
-
扩展性问题(类个数膨胀问题):
- 如果要增加一个新的电脑类型:智能手机,则要增加各个品牌下面的类
- 如果要增加一个新的品牌,也要增加各种电脑类型的类
-
违反单一职责原则
- 一个类:联想笔记本,有两个引起这个类变化的原因
-
-
总结
- 桥接模式可以取代多层继承的方案。多层继承违背了单一职责原则,复用性较差,类的个数也非常多。桥接模式可以极大的减少子类的个数,从而降低管理和维护的成本
- 桥接模式极大的提高了系统可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有的系统,符合开闭原则
-
实际开发中应用场景
-
JDBC驱动程序
-
AWT中的Peer架构
-
银行日志管理:
- 格式分类:操作日志、交易日志、异常日志
- 距离分类:本地记录日志、异地记录日志
-
-
-
人力资源系统中的奖金计算模块
- 奖金分类:个人奖金、团体奖金、激励奖金
- 部门分类:人事部门、销售部门、研发部门
-
OA系统中的消息处理
- 业务类型:普通消息、加急消息、特急消息
- 发送消息方式:系统内消息、手机短信、邮件
-
代码
以电脑分类为例
-
品牌类(Brand)——具体品牌,实现该类,重写方法
-
桥接类(Computer)
-
类型
- 台式机(Desktop)
- 笔记本(Laptop)
- ………
如果要扩展品牌/类型,在对应的类中添加即可,品牌类和类型类互不影响
- 比方说只增加了一个神州的牌子,在Brand类中,添加如下代码即可:
- 测试:
class shenzhou implements Brand{
@Override
public void sale() {
System.out.println("销售神州电脑");
}
}
Computer shenzhou = new Laptop(new shenzhou());
shenzhou.sale();
//结果——————————————————————————————————
销售神州电脑
销售笔记本
- 品牌类(Brand)
package bridge;
//品牌接口
public interface Brand {
void sale();
}
//具体品牌实现类
class Lenovo implements Brand{
@Override
public void sale() {
System.out.println("销售联想电脑");
}
}
class Dell implements Brand{
@Override
public void sale() {
System.out.println("销售戴尔电脑");
}
}
- 桥接类(Computer)
package bridge;
//桥接类
public class Computer{
protected Brand brand;
public Computer(Brand brand) {
this.brand = brand;
}
public void sale() {
brand.sale();
}
}
- 具体类型类
//电脑类型实现类,通过桥接类链接品牌
public class Desktop extends Computer{
public Desktop(Brand brand) {
super(brand);
}
@Override
public void sale() {
super.sale();
System.out.println("销售台式机");
}
}
class Laptop extends Computer{
public Laptop(Brand brand) {
super(brand);
}
@Override
public void sale() {
super.sale();
System.out.println("销售笔记本");
}
}
- 测试:
public class Client {
public static void main(String[] args) {
//销售联想笔记本
Computer lenovo = new Laptop(new Lenovo());
lenovo.sale();
}
}
//结果————————————————————————————————————
销售联想电脑
销售笔记本