[设计模式] 结构型:桥接模式(Bridge Pattern)

什么是桥接模式

从字面意思看,“桥接”就是用桥去连接的意思,桥建好后,桥两边的世界就可以相互来往了。

岁月更迭,桥本身不会有变化,但是桥两边的世界有无穷的变化,而且,两边的变化彼此独立,互不影响。

就像“灯、电线、开关”这样的实际生活场景,电线就是桥,灯和开关就是桥两边的世界,通过电线把灯和开关连接起来工作,这就是桥接模式。

灯坏了换灯,开关坏了换开关,而且,想换什么样的就换什么样的,换灯的时候不用考虑开关,换开关的时候不用考虑灯,操作起来能这么方便,全都是电线的功劳。

这也就是桥接模式的好处:

通过一座桥,解藕桥两边系统的强关联性,让它们能够独立的变化

试想一下,如果没有电线,直接把开关集成在灯上面,那么,灯和开关任何一个出现问题,两者就都得换,并且,两者紧紧的绑在一起,谁也别想离开谁,不离不弃,生死相依,这就是爱情的模样吧。

生活需要爱情,系统需要自由,玫瑰香水给你甜蜜的爱情,桥接模式给你想要的自由~~

设计与实现

现实生活中,桥能看得见,很好理解,但在编程中,桥是个抽象的概念,并不是一个具体的东西,相对来说,可能会不太好理解。

其实桥接模式很简单,就是编码的时候,抽象与实现分离,灵活运用多态。这也是很多设计模式的精髓所在。

还拿灯和开关举例子,先看看不用桥接模式的话,应该如何设计:

// 一个正常的灯
public class NormalLamp {
	public void powerOn() {
		System.out.println("开始工作");
	}

	public void powerOff() {
		System.out.println("停止工作");
	}
}

// 一个正常的开关
public class NormalSwitch {
	private NormalLamp lamp;
	
	public NormalSwitch(NormalLamp lamp) {
		this.lamp = lamp;
	}
	
	public void turnOn() {
		lamp.powerOn();
	}
	
	public void turnOff() {
		lamp.powerOff();
	}
}

// 测试方法
public static void main(String[] args) {
	NormalLamp normalLamp = new NormalLamp();
	NormalSwitch normalSwitch = new NormalSwitch(normalLamp);
	normalSwitch.turnOn();// 开
	normalSwitch.turnOff();// 关
}

稍微有点编程经验的人,可能都会看出来,这样的编码风格耦合性太强,灯NormalLamp和开关NormalSwitch强关联,换灯就必须换开关。

比如,想换个高级灯AdvancedLamp,就必须加个高级开关AdvancedSwitch,因为普通开关NormalSwitch不支持高级灯的工作。

把这段代码用桥接模式重新设计,体现出抽象和多态的思想:

// 灯的抽象
public interface Lamp {
	void powerOn();
	void powerOff();
}

// 普通的灯
public class NormalLamp implements Lamp {
	@Override
	public void powerOn() {
		System.out.println("开始工作");
	}

	@Override
	public void powerOff() {
		System.out.println("停止工作");
	}
}

// 高级的灯
public class AdvancedLamp implements Lamp {
	@Override
	public void powerOn() {
		System.out.println("高级灯开始工作");
	}

	@Override
	public void powerOff() {
		System.out.println("高级灯停止工作");
	}
}

// 普通的开关
public class NormalSwitch {
	private Lamp lamp;
	
	public NormalSwitch(Lamp lamp) {
		this.lamp = lamp;
	}

	@Override
	public void turnOn() {
		lamp.powerOn();
	}

	@Override
	public void turnOff() {
		lamp.powerOff();
	}
}

// 测试方法
public static void main(String[] args) {
	NormalLamp normalLamp = new NormalLamp();
	NormalSwitch normalSwitch = new NormalSwitch(normalLamp);
	normalSwitch.turnOn();
	normalSwitch.turnOff();
	// 换高级灯
	AdvancedLamp advancedLamp = new AdvancedLamp();
	normalSwitch = new NormalSwitch(advancedLamp);
	normalSwitch.turnOn();
	normalSwitch.turnOff();
}

这段代码对灯进行了抽象,普通开关NormalSwitch内部连接着灯的抽象Lamp,这个连接就是桥,这种编码方法就是桥接模式。

可以说,现在的普通开关NormalSwitch特别厉害,它能控制所有的灯工作,只需要给它一个具体的灯对象就好。

现在,开关不变,灯可以随便换。

再进一步,如果开关也想多样化,也要自由的更换,那就再对开关也进行一个抽象,运用上多态思想:

// 开关的抽象
public abstract class Switch {
	private Lamp lamp;

	public Switch(Lamp lamp) {
		this.lamp = lamp;
	}

	public void turnOn() {
		lamp.powerOn();
	}

	public void turnOff() {
		lamp.powerOff();
	}
}

// 普通开关
public class NormalSwitch extends Switch {
	public NormalSwitch(Lamp lamp) {
		super(lamp);
	}
}

// 高级开关
public class AdvancedSwitch extends Switch {
	public AdvancedSwitch(Lamp lamp) {
		super(lamp);
	}
}

设计到这里,灯和开关就都能自由的更换组合了。

总结

桥接模式的核心是抽象与实现的分离,运用多态机制达到运行时的多样化效果。

本文的桥接模式只涉及到两个维度的变量,灯和开关,如果业务场景复杂,也可能有多个变量维度。

桥接模式是设计模式里面很基础的一种,体现的主要是面向对象语言的两大特性:封装、多态。

设计模式,万变不离其宗:抽象与实现的分离

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章