目录
具体实现化(Concrete Implementor)角色:
现实例子
我们都去买过手机,手机按照品牌分可以分为华为、小米、oppo、vivo等品牌,如果这些手机按照内存分又可以分为6G、8G、12G等等。假如我们每一种手机都想要玩一下,至少需要4*3个。这对我们来说这些手机也太多了,竟然有12个,最主要的是手机品牌和内存是放在一起的。现在有这样一种机制,手机牌品商是一个公司,做手机内存的是一个公司,想要做什么手机我们只需要让其两者搭配起来即可。有点类似于全球贸易分工明确的思想,这就是桥接模式,把两个不同维度的东西桥接起来。
概念
桥接模式是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。它将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度,使得它们都可以独立地变化。
使用场景
如果一个系统需要在构件的抽象化和具体角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,可以通过桥接模式使它们在抽象层建立一个关联关系。对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
例如下列的使用场景:
1、银行日志管理:
1、格式分类:
操作日志、交易日志、异常日志
2、距离分类:
本地日志、异地日志。
2、人力资源系统,部门和奖金分类:
1、部门分类:
人事部门、销售部门、研发部门、采购部门、运营部门、架构部门、财务部门
2、奖金分类:
个人奖金、团队奖金、激励奖金、负激励奖金。
3、OA系统中的消息处理:
1、业务类型:
普通消息、加急消息、特急消息
2、发送消息方式:
系统内消息、站外消息、手机短信、邮件
桥接模式优缺点
优点
1、分离抽象和实现部分:把手机、内存抽象出来。实现与之分离。由于抽象与实现分离,所以扩展能力强。
2、松耦合:两个维度分开。
3、单一职责原则:每个维度各干各的活。
缺点
由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,这增加了系统的理解与设计难度。
灵魂拷问
为什么使用桥接模式不使用继承呢?
继承是一种强耦合关系,子类与父类有非常紧密的依赖关系,父类的任何变化 都会导致子类发生变化。因此才使用桥接模式,使用了桥接模式之后,我们的两个维度就像桥梁一样被链接了起来。体现了松耦合的特性。
角色构成
client
指的是我们买手机的人。
抽象化(Abstraction)角色
定义抽象类,并包含一个对实现化对象的引用。这里在这里可以形象化理解为它指的是手机抽象类。
扩展抽象化(Refined Abstraction)角色
是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。在这里可以形象化理解为它指的是具体手机品牌。
实现化(Implementor)角色
定义实现化角色的接口,供扩展抽象化角色调用。在这里相当于手机的其他组件,内存。
具体实现化(Concrete Implementor)角色:
给出实现化角色接口的具体实现。指的是具体的内存型号。
UML结构
代码实现
Implementor(实现化角色)
IMemory.java
package pattern.bridge.implementor;
/**
* 〈功能详细描述〉第一个维度:定义手机内存接口(内存大小维度)
*
* @author 刘斌
* @date 2020/3/7
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public interface IMemory {
void addMemory();
}
IScreen.java
package pattern.bridge.implementor;
/**
* 〈功能详细描述〉
*
* @author 刘斌
* @date 2020/3/7
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public interface IScreen {
void carryScreenSize();
}
Concrete Implementor(具体实现化角色)
Memory6G
package pattern.bridge.concreteimplementor.memory;
import pattern.bridge.implementor.IMemory;
/**
* 〈功能详细描述〉
*
* @author 刘斌
* @date 2020/3/7
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class Memory6G implements IMemory {
@Override
public void addMemory() {
System.out.println("安装了6G内存");
}
}
Memory8G
package pattern.bridge.concreteimplementor.memory;
import pattern.bridge.implementor.IMemory;
/**
* 〈功能详细描述〉
*
* @author 刘斌
* @date 2020/3/7
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class Memory8G implements IMemory {
@Override
public void addMemory() {
System.out.println("安装了8G内存");
}
}
Memory12G
package pattern.bridge.concreteimplementor.memory;
import pattern.bridge.implementor.IMemory;
/**
* 〈功能详细描述〉
*
* @author 刘斌
* @date 2020/3/7
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class Memory12G implements IMemory {
@Override
public void addMemory() {
System.out.println("安装了12G内存");
}
}
ScreenInch5.java
package pattern.bridge.concreteimplementor.screen;
import pattern.bridge.implementor.IScreen;
/**
* 〈功能详细描述〉
*
* @author 刘斌
* @date 2020/3/7
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class ScreenInch5 implements IScreen {
@Override
public void carryScreenSize() {
System.out.println("搭载5英寸屏幕");
}
}
ScreenInch6.java
package pattern.bridge.concreteimplementor.screen;
import pattern.bridge.implementor.IScreen;
/**
* 〈功能详细描述〉
*
* @author 刘斌
* @date 2020/3/7
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class ScreenInch6 implements IScreen {
@Override
public void carryScreenSize() {
System.out.println("搭载6英寸屏幕");
}
}
Abstraction(抽象化角色)
MobilePhone.java
package pattern.bridge.abstraction;
import pattern.bridge.implementor.IMemory;
import pattern.bridge.implementor.IScreen;
/**
* 〈功能详细描述〉
*
* @author 刘斌
* @date 2020/3/7
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public abstract class MobilePhone {
public IMemory memory;
public IScreen screen;
public void setMemory(IMemory memory) {
this.memory = memory;
}
public void setScreen(IScreen screen) {
this.screen = screen;
}
public abstract void buyPhone();
}
Refined Abstraction(扩展化抽象)
HuaWeiPhone.java
package pattern.bridge.absrefined;
import pattern.bridge.abstraction.MobilePhone;
/**
* 〈功能详细描述〉
*
* @author 刘斌
* @date 2020/3/7
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class HuaWeiPhone extends MobilePhone {
@Override
public void buyPhone() {
System.out.println("购买华为手机");
memory.addMemory();
screen.carryScreenSize();
}
}
JinLiPhone.java
package pattern.bridge.absrefined;
import pattern.bridge.abstraction.MobilePhone;
/**
* 〈功能详细描述〉
*
* @author 刘斌
* @date 2020/3/7
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class JinLiPhone extends MobilePhone {
@Override
public void buyPhone() {
System.out.println("购买金立手机");
memory.addMemory();
screen.carryScreenSize();
}
}
XiaoMiPhone.java
package pattern.bridge.absrefined;
import pattern.bridge.abstraction.MobilePhone;
/**
* 〈功能详细描述〉
*
* @author 刘斌
* @date 2020/3/7
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class XiaoMiPhone extends MobilePhone {
@Override
public void buyPhone() {
System.out.println("购买小米手机");
memory.addMemory();
screen.carryScreenSize();
}
}
桥接模式客户端调用
BridgeClient.java
package pattern.bridge;
import pattern.bridge.absrefined.HuaWeiPhone;
import pattern.bridge.absrefined.XiaoMiPhone;
import pattern.bridge.abstraction.MobilePhone;
import pattern.bridge.concreteimplementor.memory.Memory6G;
import pattern.bridge.concreteimplementor.memory.Memory8G;
import pattern.bridge.concreteimplementor.screen.ScreenInch5;
import pattern.bridge.concreteimplementor.screen.ScreenInch6;
/**
* 〈功能详细描述〉
*
* @author 刘斌
* @date 2020/3/7
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class BridgeClient {
public static void main(String[] args) {
brandBridgeMemory();
}
public static void brandBridgeMemory() {
// 让华为搭载8G内存
MobilePhone huaWeiPhone = new HuaWeiPhone();
huaWeiPhone.setMemory(new Memory8G());
huaWeiPhone.setScreen(new ScreenInch5());
huaWeiPhone.buyPhone();
System.out.println("\n=====================================>\n");
// 让小米搭载6G内存
MobilePhone xiaoMiPhone = new XiaoMiPhone();
xiaoMiPhone.setMemory(new Memory6G());
xiaoMiPhone.setScreen(new ScreenInch6());
xiaoMiPhone.buyPhone();
}
}
桥接模式控制台输出