设计模式(Java)----桥接模式Bridge

本质:分离抽象和实现
例题:手机都有通讯录和游戏功能,M品牌手机和N品牌手机都有通讯录的增删改查功能和游戏功能。

 手机品牌和手机软件之间的关系是手机品牌包含有手机软件,但软件并不是品牌的一部分,所以它们之间是聚合关系

 

 先来解释一个名词:脱耦
1、耦合:两个实体的行为的某种强关联。将它们的强关联去掉,就是耦合的解脱,或称脱耦。在这里,脱耦是指将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关联改换成弱关联。
2、将两个角色之间的继承关系改为聚合关系,就是将它们之间的强关联改换成为弱关联。
3、因此,桥接模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系,从而使两者可以相对独立地变化。这就是桥接模式的用意。

//手机软件
abstract class HandsetSoft{
	public abstract void Run();
}
//手机品牌
abstract class HandsetBrand{
	protected HandsetSoft soft;
	//设置手机软件
	public void SetHandsetSoft(HandsetSoft soft) {
		this.soft=soft;
	}
	//运行
	public abstract void Run();
}
class HandsetBrandM extends HandsetBrand{

	@Override
	public void Run() {
		// TODO Auto-generated method stub
		System.out.println("M Brand");
		soft.Run();//调用软件里的Run()方法
	}
	
}
class HandsetBrandN extends HandsetBrand{

	@Override
	public void Run() {
		// TODO Auto-generated method stub
		System.out.println("N Brand");
		soft.Run();//调用软件里的Run()方法
	}
	
}
class HandsetGame extends HandsetSoft{//手机游戏

	@Override
	public void Run() {
		// TODO Auto-generated method stub
		System.out.println("运行手机游戏");
	}
	
}
class AddressList extends HandsetSoft{//手机通讯录

	@Override
	public void Run() {
		// TODO Auto-generated method stub
		System.out.println("运行手机通讯录");
	}
}
class Mp3 extends HandsetSoft{//手机mp3

	@Override
	public void Run() {
		// TODO Auto-generated method stub
		System.out.println("运行手机mp3");
	}
	
}

public  class Main{
	public static void main(String[] args){
		HandsetBrand ab;
		ab=new HandsetBrandN();
		ab.SetHandsetSoft(new HandsetGame());
		ab.Run();
		ab.SetHandsetSoft(new AddressList());
		ab.Run();

		ab=new HandsetBrandM();
		ab.SetHandsetSoft(new HandsetGame());
		ab.Run();
		ab.SetHandsetSoft(new AddressList());
		ab.Run();
		ab.SetHandsetSoft(new Mp3());
		ab.Run();
	}
}

 结果为:
N Brand
运行手机游戏
N Brand
运行手机通讯录
M Brand
运行手机游戏
M Brand
运行手机通讯录
M Brand
运行手机mp3

扩展问题
1、如果增加一个功能,比如拍照功能,在手机软件部分增加手机拍照子类。类的个数增加也只是一个。不会影响其他任何类。
2、如果要增加S品牌,在手机品牌部分增加一个品牌子类就可以了。个数也是一个不会影响其他类。

//手机软件
abstract class HandsetSoft{
	public abstract void Run();
}
//手机品牌
abstract class HandsetBrand{
	protected HandsetSoft soft;
	//设置手机软件
	public void SetHandsetSoft(HandsetSoft soft) {
		this.soft=soft;
	}
	//运行
	public abstract void Run();
}
class HandsetBrandM extends HandsetBrand{

	@Override
	public void Run() {
		// TODO Auto-generated method stub
		System.out.println("M Brand");
		soft.Run();//调用软件里的Run()方法
	}
	
}
class HandsetBrandN extends HandsetBrand{

	@Override
	public void Run() {
		// TODO Auto-generated method stub
		System.out.println("N Brand");
		soft.Run();//调用软件里的Run()方法
	}
	
}
class HandsetBrandS extends HandsetBrand{

	@Override
	public void Run() {
		// TODO Auto-generated method stub
		System.out.println("S Brand");
		soft.Run();//调用软件里的Run()方法
	}
	
}
class HandsetGame extends HandsetSoft{//手机游戏

	@Override
	public void Run() {
		// TODO Auto-generated method stub
		System.out.println("运行手机游戏");
	}
	
}
class AddressList extends HandsetSoft{//手机通讯录

	@Override
	public void Run() {
		// TODO Auto-generated method stub
		System.out.println("运行手机通讯录");
	}
}
class Mp3 extends HandsetSoft{//手机mp3

	@Override
	public void Run() {
		// TODO Auto-generated method stub
		System.out.println("运行手机mp3");
	}
	
}
class photo extends HandsetSoft{//手机拍照

	@Override
	public void Run() {
		// TODO Auto-generated method stub
		System.out.println("运行手机拍照");
	}
	
}
public  class Main{
	public static void main(String[] args){
		HandsetBrand ab;
		ab=new HandsetBrandN();
		ab.SetHandsetSoft(new HandsetGame());
		ab.Run();
		ab.SetHandsetSoft(new AddressList());
		ab.Run();

		ab=new HandsetBrandM();
		ab.SetHandsetSoft(new HandsetGame());
		ab.Run();
		ab.SetHandsetSoft(new AddressList());
		ab.Run();
		ab.SetHandsetSoft(new Mp3());
		ab.Run();
		
		ab=new HandsetBrandS();
		ab.SetHandsetSoft(new HandsetGame());
		ab.Run();
		ab.SetHandsetSoft(new AddressList());
		ab.Run();
		ab.SetHandsetSoft(new Mp3());
		ab.Run();
		ab.SetHandsetSoft(new photo());
		ab.Run();
	}
}

运行结果:
N Brand
运行手机游戏
N Brand
运行手机通讯录
M Brand
运行手机游戏
M Brand
运行手机通讯录
M Brand
运行手机mp3
S Brand
运行手机游戏
S Brand
运行手机通讯录
S Brand
运行手机mp3
S Brand
运行手机拍照

这样的设计符合开放-封闭原则,不会修改原来的代码,而只是扩展类就行了。
合成聚合复用原则,优先使用对象的合成或聚合,而不是类继承。
继承很容易造成不必要的麻烦,其本质原因是:继承是一种强耦合的结构,父类变,子类就必须要变,所以在使用继承时一定要是“is-a"关系时再考虑使用,而不是任何时候都去使用。

 可以看出,这个系统含有两个等级结构:
由抽象化角色和提炼抽象化角色组成的抽象化等级结构。
由实现化角色和两个具体实现化角色所组成的实现化等级结构。

abstract class Implementor{
	public abstract void Operation();
}
class ConcreteImplementorA extends Implementor{

	@Override
	public void Operation() {
		// TODO Auto-generated method stub
		System.out.println("具体实现A的方法执行");
	}
	
}
class ConcreteImplementorB extends Implementor{

	@Override
	public void Operation() {
		// TODO Auto-generated method stub
		System.out.println("具体实现B的方法执行");
	}
	
}
abstract class Abstraction{
	protected Implementor implementor;
	public void SetImplementor(Implementor implementor) {
		this.implementor=implementor;
	}
	public void Operation() {
		implementor.Operation();
	}
}
class RefinedAbstraction extends Abstraction{
	public void Operation() {
		implementor.Operation();
	}
}

public  class Main{
	public static void main(String[] args){
	Abstraction ab=new  RefinedAbstraction();
	ab.SetImplementor(new ConcreteImplementorA());
	ab.Operation();
	ab.SetImplementor(new ConcreteImplementorB());
	ab.Operation();
	}
}

结果为:
具体实现A的方法执行
具体实现B的方法执行

桥接模式就是将抽象部分与它的实现部分分离,其实就是实现系统可能有多角度分类,每一种分类都可能变化,那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合。
在桥接模式中的桥接是单向的,也就是只能是抽象部分的对象去使用具体实现部分的对象,而不能反过来,也就是个单向桥

使用Bridge模式和原始解决方案的根本区别在于是通过继承还是通过合成/聚合的方式去实现一个功能需求。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值