享受代码,享受人生

SOA is an integration solution. SOA is message oriented first.
The Key character of SOA is loosely coupled. SOA is enriched
by creating composite apps.
posts - 98, comments - 2396, trackbacks - 162, articles - 45
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

Bridge Strategy 和State的区别

Posted on 2005-01-25 21:21 idior 阅读(4745) 评论(17)  编辑 收藏

Bridge Strategy State的区别

 

首先需要申明的是本文不是介绍Bridge Strategy State模式,而是讨论它们的区别,所以需要你对它们先有所了解。

 

Bridge模式用一句话来说就是将抽象和实现分离。这句话如何理解,在《Design Pattern Explained》一书中做了很详细的解释。说实话,我现在已经记不清它是怎么说的了。

 

吕震宇对此也做了解释

 

我是这样理解的:对一个事物进行抽象,得到了一个行为。 比如对Shape进行抽象,得到了Draw的行为。Draw是在哪里实现的?不是在它抽象而来的类Shape,而是在另外一个类实现的。哪个类呢?Drawing类。

Draw是从Shape抽象出来的行为,但是不在Shape中予以实现。这就是抽象和实现分离。

为什么要这样呢?因为Draw的方法可能不同,比如可以用实线,也可以用虚线。为了更好的隐藏变化,所以将其分离。由于本文不是介绍Bridge模式,不再深入介绍它的好处。

 

BTW吕震宇的文章中似乎并不是Bridge模式,因为缺少被抽象的行为,但是具有Bridge模式的思想Favor composition than inheritance,不过在这三个模式中都有这个思想,所以大家很难分清。)

 

说到这里,你有没有想到Template Method模式。为什么不用它来实现?

 

错! Template Method重在Template。你这里只是根据不同的方法(实线,虚线)重写Draw方法。那个Template方法你并没用到。

这样我们就引出了BridgeStrategy的区别。

Bridge就是将抽象出的行为交给别人做,抽象方法中就是一个简单的委托,没有使用模板方法。

Strategy就是有模板方法的Bridge。如下:


 

 

所以区别的关键在于那个抽象方法是不是Template方法。

 

再来看StrategyState模式。同样这里不会细谈State模式,相关内容可以见DP。(State模式主要描述的是有限自动机的思想)

其实这两个模式区别比较大,不过在Gof的图中没体现出来。

就拿DP书中的例子来说:




关键就在于那个
TCPStateTCPConnection的引用。

为什么书中没有这条线?因为TCPConnection是作为函数参数(Open(TCPConnection tp))传给TCPState的。TCPState本身并没有TCPConnection的引用。

为什么要有这条线,在这里强调的是在各个方法中会改变TCP连接的状态。比如当目前TCP连接处于Closed状态,那么调用Open自然会改变当前的状态使之变为TCPEstablished,而要想改变TCPConnectionstate对象,自然要传入TCPConnection的引用,然后调用SetState方法。

另外要说的是TCPConnection中的状态的变化是由TCPState来控制的,其他任何对象都不应该控制。也就是说SetState函数也只能有TCPState来调用。(其实这里应该采用类似C++友元的机制比较好)而Stradegy中的具体算法是由外界设置和改变的,而不是模式的内部活动。

 

现在你明白他们的区别了吗?比你相像的要大吧。

 

不过他们的目的都是两个:

Find what vary and encapsulate it.

Favor composition than inheritance.

 

 

 

 

Feedback

#1楼  回复 引用 查看   

2005-01-26 10:11 by 纯爷们      
我发表一点自己的意见,不知道正确与否:)

我觉得你在这里举的策略模式与桥梁模式的区别跟我的理解有点区别,我理解的策略模式在右边的抽象等级结构中应该是对算法的包装,而这个包装很可能会用到 Templet Method,也就是说Templet Method的抽象以及具体实现应该在右边的结构中而不应该在左边出现:)

是不是我的理解有问题

#2楼  回复 引用   

2005-01-26 11:08 by idior
@纯爷们
你说的也有道理,不过Bridge的右边也可以使用template.

个人以为strategy的左边通常不象Bridge那样就是一个简单的委托.

不过我的template说法有点问题,它是相对SolidDrawing和DashDrawing而说的,而不是Rectangle和Circle而言.

说来这两个模式的区别还真不像state 和他们那么明显.

#3楼  回复 引用 查看   

2005-01-28 14:03 by 吕震宇      
Bridge模式与Strategy模式的差别确实不很大。Template也仅仅展现了其差别的一个方面,何况在某些情况下两个模式都可以应用TemplateMethod模式。

就我个人理解,我认为Bridge模式强调桥的两边可以独立变化而不影响另外一边。因此我感觉你上面的两个例子都有Bridge的影子。就像我说的蜡笔与毛笔的故事一样。不过我非常赞同你说的在这个例子中“因为缺少被抽象的行为”。Strategy模式更强调算法的可互换性,而不是桥的两边可以独立变化。所以我觉得Strategy就象多用改锥,拥有可互换的改锥头。通常我们不强调改锥把如何变化,我们更关注改锥头的可互换性。

#4楼  回复 引用   

2006-03-22 15:59 by 别太较真[未注册用户]
通常我们不强调改锥把如何变化,我们更关注改锥头的可互换性。

嗯,我觉得这句话说到点子上了,我理解的也是这样。Strategy就是简化了的Bridge,只有一边在变化,而不是两边

#5楼  回复 引用   

2006-05-19 16:13 by angwin[未注册用户]
我们可以站在一个更高的高度来看bridge和strategy.
bridge为行为模式,strategy为结构模式.他们两个的应用场合不同.

#6楼  回复 引用   

2006-06-17 11:56 by experience[未注册用户]
@吕震宇
我倒是不赞同楼主所说在“蜡笔与毛笔的故事”中“缺少被抽象的行为”的说法。Bridge模式中解耦的是“抽象”与“实现”。这里的实现不一定是对“行为”的抽象,按照《Design Pattern Explained》一书中所说,这里实现是指的抽象类和它的派生类用以实现自己的某个对象(本身是抽象与其派生类构成的继承体系,要不怎么变化呢)。进一步说就是这里的抽象指的是一个概念或者说是一个继承体系中的对象,而实现则是被抽象使用并完成自己的功能的另一个继承体系。桥梁模式的目的就是让这两个继承体系可以,独立的变化、派生。蜡笔与毛笔的故事中毛笔(第一个继承体系)和颜料(第二个继承体系)可以独立的变化,所以我认为这是个非常恰当的桥梁模式的例子。

#7楼  回复 引用   

2006-06-17 12:17 by experience[未注册用户]
继续:)
我觉得区分两个模式的方法不是从模式的实现上面看,因为一个模式的实现往往夹杂了其它的模式,比如idior给的第一个例子中就有Template Method模式。我赞成吕震宇的说法,这里面有Bridge模式的影子,甚至我觉得不止是影子,这本身是一个Bridge模式的例子。
区分两个模式的方法应该从解决的问题上看,也就是从context上分析。
我觉得简单的说Strategy模式是从N变化为1+N,原来有N个类但是这N个类里面只有某个算法的区别,我们把N个算法提取出来就变成了1个抽象类(不要理解成Java中的abstract class,而是这个抽象类表示一个概念)和N个实现类(同理,不要理解成对前面那个抽象类的实现,而是辅助实现抽象类的某个功能的一个继承体系)。注意这里只有一个继承体系。
而Bridge模式是从M×N变化为M+N,原来系统中有M×N个类,但是从中可以提取出N个算法(或者辅助类)和M个主体(我想不出一个好的名次)。这样构成了两个继承体系,N个算法(颜料)构成一个继承体系,M个主体类(毛笔的不同型号)构成一个继承体系。两个继承体系可以独立的变化。
从解决的问题上看,二者都要解决重复代码的问题,但是前者不强调锥把(见吕震宇的回复)的变化,而后者强调,并且强调锥头和所有锥把的兼容。我认为这才是二者的根本区别。
这是我个人的理解,与楼主商榷。

#8楼  回复 引用   

2006-11-16 15:27 by champion[未注册用户]
楼上的说的太经典了,我完全赞同!
N->N+1
M×N->M+N
这个说法非常到位,易于理解,赞!

#9楼  回复 引用   

2006-12-26 22:15 by Mole[未注册用户]
个人觉得后面几位都说得比较在理。
不过我在考虑桥接时经常会觉得,该模式对于implementor的接口设计提出了很高的要求。和Strategy不同,在Bridge中,处于较高抽象层次的Abstraction自己也会有自己的继承树,而且随时会加入新的子类,甚至变成一个很复杂的层次结构(这应该是Bridge模式设计的目的之一)。但是implementor的接口是在最初就规定好的,利用这些接口是否能适应后面不断变化的Abstraction的子类的要求?
在系统设计之初,弄清哪些是抽象哪些是实现看来是很考查功力的一件事情。

#10楼  回复 引用   

2007-04-11 15:40 by 模式需要磨[未注册用户]
Strategy:是一个锥把可以使用多个锥头;
Bridge:是不同锥把可以使用多个锥头;

当Bridge的左边只有一个时就退化为Strategy了!

#11楼  回复 引用 查看   

2007-07-18 20:26 by 炭炭      
Strategy:是一个锥把可以使用多个锥头;
Bridge:是不同锥把可以使用多个锥头;

当Bridge的左边只有一个时就退化为Strategy了!
____________________

这才说到点上了。不只是context 不一样,表现就是不一样的!

#12楼  回复 引用   

2007-12-05 11:30 by 非说不可吗[未注册用户]
开始觉得他们很相似,但是后来发现完全不一样,也不是说bridge退化就成了stragery,前者是结构模式,前者2边是独立的,两边通过最上面的桥来连系.后者是行为模式,强调的是在一个context下有不同算法可供动太的切还,我认为动太切换的实现之1就是在context中有个set方法可供外部调用.