结构性设计模式------桥接模式
桥接模式:将抽象部分与其实现部分分离,使他们可以独立地变化。即通过将实现和抽象放在两个不同的层次中而使它们可以独立改变。这里的抽象指的是类的功能层次结构,实现指的是类的实现层次结构。
类的功能层次结构:体现在类的功能的扩展上(个人理解为内在扩展性,即手机本身的不同特性),例如手机类,手机有4G通信、5G通信,而4G通信的实现和5G是不一样的。
类的实现层次结构:体现在类的实现上(个人理解为外在扩展性,即对象内部的假设不会再变化,而是不同的表现形式),例如手机类,我们有华为手机的4G/5G实现,苹果手机的4G/5G实现。
总体来说,就是类在两个维度上都需要且都可以扩展的时候,可以使用桥接将这个两个维度划分开。(所以,当我们有一个对象存在多个维度,且每个维度都需要扩展时,可以考虑桥接)
桥接与适配的区别:
桥接模式一般都是先有桥,再去扩展两端。
适配器一般都是开发后期,两边的接口都已经成熟不易更改了,才需要适配器去适配,所以是先有两端,再用适配器当作中间桥梁去适配。
//不使用桥接
interface Phone{
void call();
void online();
}
//功能扩展
class Phone_4G implements Phone{
@Override
public void call() {
System.out.println("使用4G手机打电话");
}
@Override
public void online() {
System.out.println("使用4G手机上网");
}
}
class Phone_5G implements Phone{
@Override
public void call() {
System.out.println("使用5G手机打电话");
}
@Override
public void online() {
System.out.println("使用5G手机上网");
}
}
//此时,由于手机从实现维度来说又分为华为手机、苹果手机。
class HuaWeiPhone4G extends Phone_4G{
//....
}
class HuaWeiPhone5G extends Phone_5G{
//....
}
class IPhone4G extends Phone_4G{
//....
}
class IPhone5G extends Phone_5G{
//....
}
/*
这样,功能层次结构就和实现层次结构耦合在了一起,当手机需要新增一个功能的时候,
例如6G功能,就需要每种实现(手机品牌)也添加相应的不同实现。
而如果要新增一个新的实现(新的手机品牌,例如小米),就需要新增手机所提供的所有功能对应的实现
*/
使用桥接模式:
//使用桥接模式,将手机实现----即手机品牌这个维度抽离出来,将手机的功能层次和实现层次组合起来.
//将功能组合到实现中
//而不是通过继承的方式将两个层次结合在一起。
public interface Phone {
void call();
void online();
}
public class Phone4G implements Phone {
@Override
public void call() {
System.out.println("使用4G手机打电话");
}
@Override
public void online() {
System.out.println("使用4G手机上网");
}
}
public class Phone5G implements Phone {
@Override
public void call() {
System.out.println("使用5G手机打电话");
}
@Override
public void online() {
System.out.println("使用5G手机上网");
}
}
//实现部分,不再采用继承的方式,而是采用组合的方式,将实现层次抽离出来。
/*
此时,如果手机的功能结构发生变化,假如增加了6G通信的功能实现,则手机方面不需要再增加额外的类去实现
而且手机的实现结构发生变化,即增加新的手机品牌,也不会影响到功能结构,使用继承也不会影响功能结构,
但是需要为每种功能实现都添加一个新的实现类。
采用这种组合的方式,只需要新增一个类就可以了。
手机的实现部分应该也是需要抽象出一个接口来的,这里为了方便省掉了
*/
public class HuaWeiPhone {
private Phone phone;
public HuaWeiPhone(Phone phone){
this.phone = phone;
}
public void call(){
System.out.println("华为手机");
phone.call();
}
public void online(){
System.out.println("华为手机");
phone.online();
}
}
public class IPhone {
private Phone phone;
public IPhone(Phone phone){
this.phone = phone;
}
public void call(){
System.out.println("苹果手机");
phone.call();
}
public void online(){
System.out.println("苹果手机");
phone.online();
}
}