设计模式学习笔记(28)——桥接模式实现

桥接模式
一、脱藕

  • 耦合,就是两个实体的行为的某种强关联。而将它们的强关联去掉,就是耦合的解脱,或称脱耦。
  • 脱耦是指将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关联改换成弱关联。
    • 将两个角色之间的继承关系改为聚合关系,就是将它们之间的强关联改换成为弱关联。
  • 桥连模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系,从而使两者可以相对独立地变化。这就是桥连模式的用意。
    二·、例题
    手机都有通讯录和游戏功能,M品牌手机和N品牌手机都有通讯录的增删改查功能和游戏功能。
  • 父类是‘手机品牌’,下有‘手机品牌M’ 和‘手机品牌N’ ,每个子类下各有‘通讯录’和‘游戏’ 子类。
  • 父类是‘手机软件’,下有‘通讯录’ 和‘游戏’ 子类,每个子类下各有‘手机品牌M’和‘手机品牌N’。
    三、紧耦合的程序演化
    1.如果现在有一个N品牌的手机,它有一个小游戏,我要玩游戏,程序该如何写。
    先写一个此品牌的游戏类,再用客户端调用。
package operation;
//游戏类
//N品牌手机中的游戏
class HandsetNGame
{
	public void Run()
	{System.out.print("运行N品牌的手机游戏");}}

public  class Main{
	public static void main(String[] args){
		HandsetNGame game=new HandsetNGame();
		game.Run();
	}
}

2.现在又有一个M牌手机,也有小游戏,客户端也可以调用,如何做。
两个品牌,都有游戏,从面向对象的思想来说,应该有一个父类“手机品牌游戏”,然后让N和M牌手机游戏都继承于它,这样可以实现同样的运行方法。

package operation;

abstract  class HandsetGame
{
	public abstract void Run();
	}
class HandsetMGame extends HandsetGame{
	public void Run() {
		System.out.print("运行M牌手机游戏");
	}
}
class HandsetNGame extends HandsetGame{
	public void Run() {
		System.out.print("运行N牌手机游戏");
	}
}
public  class Main{
	public static void main(String[] args){
		HandsetNGame game=new HandsetNGame();
		game.Run();
		HandsetMGame game1=new HandsetMGame();
		game1.Run();
	}
}

3.由于手机都需要通讯录功能,于是N品牌手机和M品牌手机都增加了通讯录的增删查改功能。
在这里插入图片描述

package operation;

abstract  class HandsetBrand
{
	public abstract void Run();
	}
class HandsetBrandM extends HandsetBrand{

	@Override
	public void Run() {
		// TODO Auto-generated method stub
		
	}
	
	
}
class HandsetBrandN extends HandsetBrand{

	@Override
	public void Run() {
		// TODO Auto-generated method stub
		
	}
	
	
}
class HandsetBrandMGame extends HandsetBrandM{
	public void Run() {
		System.out.print("运行M牌手机游戏");
	}
}
class HandsetBrandNGame extends HandsetBrandN{
	public void Run() {
		System.out.print("运行N牌手机游戏");
	}
}
class HandsetBrandMAdressList extends HandsetBrandM{
	public void Run() {
		System.out.print("运行M牌通讯录");
	}
}
class HandsetBrandNAdressList extends HandsetBrandN{
	public void Run() {
		System.out.print("运行N牌通讯录");
	}
}
public  class Main{
	public static void main(String[] args){
		HandsetBrand ab;
		ab=new HandsetBrandMAdressList();
		ab.Run();
		ab=new  HandsetBrandMGame();
		ab.Run();
		ab=new HandsetBrandNAdressList();
		ab.Run();
		ab=new HandsetBrandMGame();
		ab.Run();
	}
}

还有一种
在这里插入图片描述也不能解决
问题:
很多情况用继承会带来麻烦。
对象的继承关系是在编译时就定义好了,所以无法在运行时改变从父类继承的实现。子类的实现与它的父类有非常紧密的依赖关系,父类实现中的任何变化必然会导致子类发生变化。需要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。
四、合成/聚合复用原则
合成/聚合复用原则(CAPP),尽量使用合成/聚合,尽量不要使用类继承。
合成和聚合都是关联的特殊种类。聚合表示一种弱的“拥有”关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分;合成则是一种强的“拥有”关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。
好处是,优先使用对象的合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。
在这里插入图片描述五、松耦合程序

package operation;

abstract class HandsetSoft
{public abstract void Run();}
class HandsetGame extends HandsetSoft{
	public void Run() {
		System.out.print("运行手机游戏");
	}
}
class HandsetAdressList extends HandsetSoft{
	public void Run() {
		System.out.print("运行手机通讯录");
	}
}
abstract class HandsetBrand{
	protected HandsetSoft soft;
	public void SetHandsetSoft(HandsetSoft soft) {
		this.soft=soft;
	}
	public abstract void Run();
}
class HandsetBrandN extends HandsetBrand{
	public void Run() {soft.Run();}
}
class HandsetBrandM extends HandsetBrand{
	public void Run() {soft.Run();}
}
public  class Main{
	public static void main(String[] args){
		HandsetBrand ab;
		ab=new HandsetBrandN();
		ab.SetHandsetSoft(new HandsetGame());
		ab.Run();
		ab.SetHandsetSoft(new HandsetAdressList());
		ab.Run();
		ab=new HandsetBrandM();
		ab.SetHandsetSoft(new HandsetGame());
		ab.Run();
		ab.SetHandsetSoft(new HandsetAdressList());
		ab.Run();
	}
}

六、桥接模式
桥接模式,将抽象部分与它的实现部分分离,使它们都可以独立地变化。
什么叫抽象与它的实现分离,实现指的是抽象类和它的派生类用来实现自己的对象。
按品牌分类实现的结构图
在这里插入图片描述
按软件分类实现结构图
在这里插入图片描述由于实现模式有多种,桥接模式的核心意图就是把这些实现独立出来,让它们各自变化。

在这里插入图片描述七、桥接模式基本代码
在这里插入图片描述

package operation;

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

	public void Operation() {
		System.out.println("具体实现A的方法执行");
	}
	
}
class ConcreteImplementorB extends Implementor{
 

	public void Operation() {
		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();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值