bridge模式和stradegy模式的区别

from:http://hi.baidu.com/zhizhesky/blog/item/6432017b899766f80bd18737.html

下边三段分别来自CSDN论坛的贴子和一篇blogjava的文章,看了之后令我茅塞顿开,为表尊重不在冗述,直接贴原文了。

实际上所有模式可以只分为类模式和对象模式两种,类模式是用继承而对象模式是用委托  
Bridge模式和Strategy模式相似就是因为他们都将任务委托给了另外一个接口的具体实现,  
他们之间的区别在于Bridge的目的是让底层实现和上层接口可以分别演化,从而提高移植性  
而Strategy的目的是将复杂的算法封装起来,从而便于替换不同的算法。  
因此可以想象一般情况下Bridge的实现几乎不会在运行时更改而Strategy的算法则很有可能  
需要在运行时更换,这就导致在细节方面需要考虑的因素可能会很不相同。

strategy模式是为了扩展和修改,并提供动态配置。它往往可以在同一环境当中使用不同的策略,就是调用不同的派生类。其内部实现是自由的,不受已有的类接口的限制(很多时候根本就不调用现成的接口)。  
bridge模式是往往是为了利用已有的方法或类。它将原来不统一,不兼容的接口封装起来,变成统一的接口。它的应用往往是不同的环境或平台下只能选择一 种,比如说在windows平台下只能用WinClass,而在unix平台下只能用UnixClass.它的主要作用不是配置而是定义通用接口。  
据个例子来说:我要画园,要实心园,我可以用SolidPen来配置,画虚线园可以用dashedPen来配置。这是strategy模式。  
而同样是画园,我是在windows下来画实心园,就用windowPen+solidPen来配置,在unix下画实心园就用 unixPen+solidPen来配置。如果要再windows下画虚线园,就用windowsPen+dashedPen来配置,要在unix下画虚 线园,就用unixPen+dashedPen来配置。  
我这里仅仅是就一种情况来说strategy和bridge的组合应用,其他的组合可能性随环境变化而多种多样。从中可以看出,bridge和strategy是可能组合使用,侧重不同方面的。  
模式某种角度上来讲就是对象组合。不要看他们都是对象组合就好像是一样的。模式的动机,意图,使用场合,组合方式,这些都是模式的一部分。其中细微的不同足以区分不同的模式。

 

 

桥接(Bridge)模式是结构型模式的一种,而策略(strategy)模式则属于行为模式。以下是它们的UML结构图。

在桥接模式中,Abstraction通过聚合的方式引用Implementor。

从桥接模式与策略模式谈起 - 一半是火焰,一半是海水 - BlogJava - silence - 守望者

在策略模式中,Context也使用聚合的方式引用Startegy抽象接口。

从桥接模式与策略模式谈起 - 一半是火焰,一半是海水 - BlogJava - silence - 守望者

从他们的结构图可知,在这两种模式中,都存在一个对象使用聚合的方式引用另一个对象的抽象接口的情况,而且该抽象接口的实现可以有多种并且可以替换。可以说两者在表象上都是调用者与被调用者之间的解耦,以及抽象接口与实现的分离。

那么两者的区别体现在什么地方呢?

1. 首先,在形式上,两者还是有一定区别的,对比两幅结构图,我们可以发现,在桥接模式中不仅Implementor具有变化 (ConcreateImplementior),而且Abstraction也可以发生变化(RefinedAbstraction),而且两者的变化 是完全独立的,RefinedAbstraction与ConcreateImplementior之间松散耦合,它们仅仅通过Abstraction与 Implementor之间的关系联系起来。而在策略模式中,并不考虑Context的变化,只有算法的可替代性。

2. 其次在语意上,桥接模式强调Implementor接口仅提供基本操作,而Abstraction则基于这些基本操作定义更高层次的操作。而策略模式强调 Strategy抽象接口的提供的是一种算法,一般是无状态、无数据的,而Context则简单调用这些算法完成其操作。

3. 桥接模式中不仅定义Implementor的接口而且定义Abstraction的接口,Abstraction的接口不仅仅是为了与 Implementor通信而存在的,这也反映了结构型模式的特点:通过继承、聚合的方式组合类和对象以形成更大的结构。在策略模式中,Startegy 和Context的接口都是两者之间的协作接口,并不涉及到其它的功能接口,所以它是行为模式的一种。行为模式的主要特点就是处理的是对象之间的通信方 式,往往是通过引入中介者对象将通信双方解耦,在这里实际上就是将Context与实际的算法提供者解耦。

所以相对策略模式,桥接模式要表达的内容要更多,结构也更加复杂。桥接模式表达的主要意义其实是接口隔离的原则,即把本质上并不内聚的两种体系区别 开来,使得它们可以松散的组合,而策略在解耦上还仅仅是某一个算法的层次,没有到体系这一层次。从结构图中可以看到,策略的结构是包容在桥接结构中的,桥 接中必然存在着策略模式,Abstraction与Implementor之间就可以认为是策略模式,但是桥接模式一般Implementor将提供一系 列的成体系的操作,而且Implementor是具有状态和数据的静态结构。而且桥接模式Abstraction也可以独立变化。

Bridge  例子: Bridge遵循的是接口隔离原则的典型。如 JDBC, 我们都知道JDBC是使用Bridge模式进行设计的,DriverManager就是其中的Abstraction,java.sql.Driver是Implementor,com.mysql.jdbc.Driver是Implementor的一个具体实现(请参考GOF的Bridge模式的描述)。大家注意了,前一个Driver是一个接口,后者却是一个类,它实现了前面的Driver接口。

还有 现在流行的DAO 接口规范

其他例子:

  1. abstract   class  Shape{   
  2.      public   void  draw();   
  3. }   
  4.   
  5. //这里业务出现了多种画图方式,DP1,DP2……   
  6. //抽象出接口出DP1,DP2   
  7. interface  Drawing{   
  8.      public   void  drawLine();   
  9.      public   void  drawCircle();   
  10. }   
  11.   
  12. class  V1Drawing{   
  13.      public   void  drawLine(){};   
  14.      public   void  drawCircle(){};   
  15. }   
  16.   
  17. class  V2Drawing{   
  18.      public   void  drawLine(){};   
  19.      public   void  drawCircle(){};   
  20. }   
  21.   
  22. //使用组合 ,聚集Drawing   
  23. class  Rectangle  extends  Shape{   
  24.      public   void  draw(Drawing dp){   
  25.         dp.drawLine();   
  26.     }   
  27. }   
  28.   
  29. class  Circle  extends  Shape{   
  30.      public   void  draw(Drawing dp){   
  31.         dp.drawCircle();   
  32.     }   
  33. }
  34. //抽象类Shape的派生类,使用一组实现(DP1,DP2)的接口
  35. //使得派生类不依赖于一组具体的实现,从设计模式而言,这称为Bridge模式

Stategy 例子:

 

首先,我们建立一个抽象类RepTempRule 定义一些公用变量和方法:

public abstract class RepTempRule{

protected String oldString="";
public void setOldString(String oldString){
this.oldString=oldString;
}

protected String newString="";
public String getNewString(){
return newString;
}



public abstract void replace() throws Exception;


}

在RepTempRule中 有一个抽象方法abstract需要继承明确,这个replace里其实是替代的具体方法.
我们现在有两个字符替代方案,
1.将文本中aaa替代成bbb;
2.将文本中aaa替代成ccc;

对应的类分别是RepTempRuleOne RepTempRuleTwo

public class RepTempRuleOne extends RepTempRule{


public void replace() throws Exception{

//replaceFirst是jdk1.4新特性
newString=oldString.replaceFirst("aaa", "bbbb")
System.out.println("this is replace one");

}


}

public class RepTempRuleTwo extends RepTempRule{


public void replace() throws Exception{

newString=oldString.replaceFirst("aaa", "ccc")
System.out.println("this is replace Two");

}


}

第二步:我们要建立一个算法解决类,用来提供客户端可以自由选择算法。

public class RepTempRuleSolve {

  private RepTempRule strategy;

  public RepTempRuleSolve(RepTempRule rule){
this.strategy=rule;
}

  public String getNewContext(Site site,String oldString) {
return strategy.replace(site,oldString);
}

  public void changeAlgorithm(RepTempRule newAlgorithm) {
strategy = newAlgorithm;
}

}

 

 

调用如下:

public class test{

......

  public void testReplace(){

  //使用第一套替代方案
RepTempRuleSolve solver=new RepTempRuleSolve(new RepTempRuleSimple());
solver.getNewContext(site,context);

  //使用第二套

  solver=new RepTempRuleSolve(new RepTempRuleTwo());
solver.getNewContext(site,context);

  }

.....

}

我们达到了在运行期间,可以自由切换算法的目的。

实际整个Strategy的核心部分就是抽象类的使用,使用Strategy模式可以在用户需要变化时,修改量很少,而且快速.

Strategy和Factory有一定的类似,Strategy相对简单容易理解,并且可以在运行时刻自由切换。Factory重点是用来创建对象。

Strategy适合下列场合:

1.以不同的格式保存文件;

2.以不同的算法压缩文件;

3.以不同的算法截获图象;

4.以不同的格式输出同样数据的图形,比如曲线 或框图bar等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值