JAVA设计模式之桥接模式

一、桥接模式简介

Bridge 模式又叫做桥接模式,是构造型的设计模式之一。Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展。

二、桥接模式的结构

在这里插入图片描述

三、桥接模式的角色与职责

  • Client: Bridge模式的使用者
  • Abstraction: 抽象类接口(接口或抽象类)维护对行为实现(Implementor)的引用
  • Refined Abstraction: Abstraction子类
  • Implementor: 行为实现类接口 (Abstraction接口定义了基于Implementor接口的更高层次的操作)
  • ConcreteImplementor: Implementor子类

四、桥接模式的具体实现

现在有一家遥控器制造厂商和多家电视机制造商,每个电视机制造商的遥控器底层实现都不一样,并且在积极的更新换代,而遥控器制造商对于遥控器的制造也是精益求精,从原来的一大堆按键到极简形式的遥控器,各领风骚。

1、不使用桥接模式

方案设计

我们来看看这种一种无耻的方案。
在这里插入图片描述

类设计

首先是基本的电视机厂商实现接口:

// An highlighted block
package design.bridge.gys.nobridge;
public abstract class Control {
 abstract void on();
 abstract void off();
 abstract void setChannel(int channel);
}

来看看Sony和LG厂商的底层实现:

// An highlighted block
package design.bridge.gys.nobridge;
public class SonyControl extends Control{
 @Override
 void on() {
  // TODO Auto-generated method stub
  System.out.println("Sony TV on");
 }
 @Override
 void off() {
  // TODO Auto-generated method stub
  System.out.println("Sony TV off");
 }
 @Override
 void setChannel(int channel) {
  // TODO Auto-generated method stub
  System.out.println("Channel :"+channel);
 }
}
// An highlighted block
package design.bridge.gys.nobridge;
public class LGControl extends Control{ 
 @Override
 void on() {
  // TODO Auto-generated method stub
  System.out.println("LG TV on");
 }
 @Override
 void off() {
  // TODO Auto-generated method stub
  System.out.println("LG TV off");
 }
 @Override
 void setChannel(int channel) {
     // TODO Auto-generated method stub
  System.out.println("Channel :"+channel);
 }
}

上面的是电视机厂商的底层,接下来的是遥控器厂商的一个设计形式:

// An highlighted block
package design.bridge.gys.nobridge;
public interface TVControl {
 void  OnOff();
 void preChannel();
 void nextChannel();
}

够简单的啊,音量键都没有。不管这个,看看给Sony和LG设计的遥控器吧。
Sony:

// An highlighted block
package design.bridge.gys.nobridge;
public class Sony  extends SonyControl implements TVControl{
 boolean state=false;
 int channel=0;
 @Override
 public void OnOff() {
  // TODO Auto-generated method stub
  if(state==false)
  {super.on();
  state=true;}
  else
  {super.off();
  state=false;} 
 }
 @Override
 public void preChannel() {
  // TODO Auto-generated method stub
  if(channel>0)
   channel--;
  else
   channel=200;
  super.setChannel(channel);
 }
 @Override
 public void nextChannel() {
  // TODO Auto-generated method stub
  if(channel<200)
   channel++;
  else
   channel=1;
  super.setChannel(channel);
 }
}

LG:

// An highlighted block
package design.bridge.gys.nobridge;
public class LG extends LGControl implements TVControl{
 boolean state=false;
 int channel=1;
 @Override
 public void OnOff() {
  // TODO Auto-generated method stub
  if(state==false)
  {super.on();
  state=true;}
  else
  {super.off();
  state=false;}  
 }
 @Override
 public void preChannel() {
  // TODO Auto-generated method stub
  if(channel>1)
   channel--;
  else
   channel=200;
  super.setChannel(channel);
 }
 @Override
 public void nextChannel() {
  // TODO Auto-generated method stub
  if(channel<199)
   channel++;
  else
   channel=1;
  super.setChannel(channel);
 }
}

遥控器厂家的老板怕是要被两家老总打死。打开遥控器看电视吧:

// An highlighted block
package design.bridge.gys.nobridge;
public class Test {
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  Sony sc=new Sony();
  LG lc=new LG();
  sc.on();
  sc.nextChannel();
  sc.nextChannel();
  sc.preChannel();
  sc.off();
  lc.on();
  lc.preChannel();
  lc.preChannel();
  lc.off();
 }
}

看看效果:

// An highlighted block
Sony TV on
Channel :1
Channel :2
Channel :1
Sony TV off
LG TV on
Channel :200
Channel :199
LG TV off

人模狗样还能运行起来哈。
这时候我们发现当遥控器厂商有n种类型遥控器时,再加上n个电视机制造商,我们需要n*n个遥控器类。实实在在的类爆炸啊。

2、使用桥接模式

好了,现在我们可以使用桥接模式来解决这个问题。

方案设计

在这里插入图片描述

类设计

和之前一样定义一个基本的电视接口,各个厂商均实现该接口,但是在底层有不同的实现。
现在遥控器厂商也做出了改变,技术主管做出了决定,设计一个接口,并且包含一个电视机厂商接口的域,以后每个遥控器新设计方案都继承这个接口:

// An highlighted block
package design.bridge.gys.bridge;
public abstract class Remote {
 TV tv;
 public Remote(TV tv) {
  super();
  this.tv = tv;
 }
 public abstract void onOff(); 
 public abstract void preChannel();
 public abstract void nextChnnel();
}

该抽象类中包含了一个域和三个抽象方法,以供子类实现。该设计方案一出,立马引起的关注,新一代遥控器出现了:

// An highlighted block
package design.bridge.gys.bridge;
public class RemoteControl1 extends Remote{
 boolean state=false;
 int channel=1;
 public RemoteControl1(TV tv) {
  super(tv);
  // TODO Auto-generated constructor stub
 }
 @Override
 public void onOff() {
  // TODO Auto-generated method stub
  if(state==false)
   {tv.on();
   state=true;}
  else
   {tv.off();
   state=false;}
 }
 @Override
 public void preChannel() {
  // TODO Auto-generated method stub
  if(channel>1)
   channel--;
  else 
   channel=200;
  tv.setChannel(channel);
 }
 @Override
 public void nextChnnel() {
  // TODO Auto-generated method stub
  if(channel<199)
   channel++;
  else 
   channel=1;
  tv.setChannel(channel);
 }
}

大功告成,是骡子是马拉出来溜溜啊。

// An highlighted block
package design.bridge.gys.bridge;
public class Test {
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  RemoteControl1 ct1=new RemoteControl1(new SonyControl());
  RemoteControl1 ct2=new RemoteControl1(new LGControl());
  ct1.onOff();
  ct1.preChannel();
  ct1.nextChnnel();
  ct1.nextChnnel();
  ct1.onOff();
  System.out.println("-----------");
  ct2.onOff();
  ct2.preChannel();
  ct2.preChannel();
  ct2.preChannel();
  ct2.onOff();
 }
}

看结果看结果:

// An highlighted block
Sony TV on
Channel :200
Channel :1
Channel :2
Sony TV off
-----------
LG TV on
Channel :200
Channel :199
Channel :198
LG TV off

很好,这次的复杂度没那么大了,代码也简单易懂。
掌声响起来。
其余的类:

// An highlighted block
package design.bridge.gys.bridge;
public interface TV {
 void on();
 void off();
 void setChannel(int channel);
}
// An highlighted block
package design.bridge.gys.bridge;
public class LGControl implements TV{
 @Override
 public void on() {
  // TODO Auto-generated method stub
  System.out.println("LG TV on");
 }
 @Override
 public void off() {
  // TODO Auto-generated method stub
  System.out.println("LG TV off");
 }
 @Override
 public void setChannel(int channel) {
     // TODO Auto-generated method stub
  System.out.println("Channel :"+channel);
 }
}
// An highlighted block
package design.bridge.gys.bridge;
public class SonyControl implements TV{
 @Override
 public void on() {
  // TODO Auto-generated method stub
  System.out.println("Sony TV on");
 }
 @Override
 public void off() {
  // TODO Auto-generated method stub
  System.out.println("Sony TV off");
 }
 @Override
 public void setChannel(int channel) {
  // TODO Auto-generated method stub
  System.out.println("Channel :"+channel);
 }
}

五、桥接模式与策略模式的异同

  1. 桥接的目的让接口的实现和抽象可以分别演化,从而提高移植性;策略的目的是将复杂的算法进行封装,实现替换。
  2. 桥接是使用已有的方法或者类;策略为了扩展修改并提供动态配置。
  3. 桥接强调的是接口对象仅提供基本操作;策略的接口提供一种算法。

要抱抱才会开心呀~~~~~~~~~~~~

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值