我知道,这个问题被多次询问过,但我做了一些研究但仍然没有得到它,可能你可以帮助我: 如前所述,UML几乎相同。此外,实现和想法或多或少相同:您可以定义一个Interface,而不是子类型,它封装了一些逻辑,让它传递给一个抽象。 所以,即使是微软博客人员
简单的答案是“它们相似但不同”。该 实现是类似的,但意图是不同的。给 一个类比,城市公交车和校车都是类似的车辆,但是 它们用于不同的目的。一个用来运送人 在城市的各个部分之间作为通勤服务。另一个是 用于将孩子送到学校。
“如果它看起来像一只鸭子,看起来像一只鸭子,但它打算成为一只天鹅,它可以是其中之一”,这就是我在这里读到的。
由于我还没有得到它,所以我深入挖掘:
此线程也不会添加任何新内容,除了:
它们在表面上看起来也一样。主要的 我看到的差异是在Bridge模式中的事实 抽象是对象的一部分,但在战略模式中 抽象是由对象执行的。
但是,如果我们阅读战略的定义:
定义一系列算法,封装每个算法并制作它们 互换。策略让算法独立于 使用它的客户。
没有任何定义,如何应用该策略。它也可以很容易地成为摘要上的接口,与LINQ-Orderby等常见的策略实现完全相同。
这个主题的另一个兴趣在于:
http://game-engineering.blogspot.ch/2008/07/bridge-pattern-vs-strategy-pattern.html
这个话题的主要部分:
当你想改变行为时,你会说“策略”,而你却不这样做 通过编写不同的对象,但引入一个类heirarchy。您 当你希望你改变界面和界面时说“桥” 实施。在这两种情况下,您都可以提供灵活性 改变实施;在一座桥上,你也期待着 界面改变。
这可能是主要区别吗?由于执行器和抽象是如此松散耦合,我可以改变执行器的接口,抽象不必关心?这听起来很合理,但是由于它们是有联系的,所以也不会有抽象改变吗?这不会破坏信息隐藏和DRY等所有其他原则吗?
我还看了很多很多例子,我没有在这里添加这些例子,我找不到这些模式的例子,我无法改变以适应另一个。无论是通过Interface-Property还是参数。
我在这里错过了什么吗?可能任何人都有一个真实生活的例子“我想使用策略,但Bridge确实更合适”,反之亦然,例如?
编辑:为什么我为这个主题辩护(再次)?首先,所提到的线程的接受答案如下
据我了解,你正在使用策略模式 抽象可以从外部源提供的行为 (例如,config可以指定加载一些插件程序集),你就是 当你使用相同的结构来制作你的桥时使用桥模式 代码有点整洁。实际代码看起来非常相似 - 你是 只是因为略有不同的原因而应用这些模式。
我在之前的解释中已经提到,外部源的抽象行为正是Strategy-和Bridge-Pattern的定义。
另外
当你使用相同的结构时,你正在使用桥接模式 使你的代码更整洁。
此外,策略模式使代码更加整洁,因为它抽象了整个构建块,从而使代码收紧了很多。
我认为,阅读整个主题的任何人都认为,这个主题的内容比这2个句子还要多。
答案 0 :(得分:3)
我检查了原始design patterns book,看看作者是如何定义Bridge模式的。他们的现实生活考试显示了抽象和实现层次结构可以独立更改的情况(即可以为抽象引入新的子类;可以为实现引入新的子类)。他们的例子涉及可以用于不同窗口系统的窗口库。在最初的例子中,作者使用了IBM的不同窗口系统,但我相信当前最好的类比将是不同的Linux窗口管理器(GNOME,KDE等)。因此,想象一下Window抽象,以及GNOME和KDE的两个实现。现在假设您要添加新的Window子类TransparentWindow。 TransparentWindow扩展Window,如GNOMEWindow和KDEWindow。但是你还必须为TransparentWindow提供imlement:GNOMETransparentWindow和KDETransparentWindow。等级开始看起来凌乱。想象一下新型窗口或新窗口管理器 - XFCE。为了避免复杂的层次结构,它们引入了Bridge模式,并使两个层次结构分离(即TransparentWindow扩展Window; GNOMEWindow和KDEWindow扩展WindowImpl)。对我而言,似乎一个棘手的部分是为实现定义接口,因为抽象的层次结构将需要仅使用该接口来定义它们的操作。我喜欢的Bridge模式的学习示例是here,我喜欢它,因为它不使用人工类ConcreteImplementor1和ConcreteImplementor2。谈到现实生活中的例子,我相信我在Selenium WebDriver实现中看到了这种模式,但我现在并不是100%肯定。
答案 1 :(得分:2)
用于桥模式的维基百科UML图:
What is the difference between the bridge pattern and the strategy pattern?
主要区别:抽象和实施可以独立改变。
关于您的其他疑问:
这可能是主要区别吗?由于执行器和抽象是如此松散耦合,我可以改变执行器的接口和抽象不必关心?这听起来很合理,但是也不会有抽象改变,因为它们是有联系的吗?
看看下面的代码示例@
When do you use the Bridge Pattern? How is it different from Adapter pattern?
即使示例是在java中,c#开发人员也可以轻松理解。
在链接示例中:
Vehicle : Abstraction
Car : Re-defined Abstraction
Truck : Re-defined Abstraction
Implementor : GearShifter
ConcreteImplementor: ManualGearShifter
ConcreteImplementor: AutoGearShifter
注释记号:
现在Vehicle
和GearShifter
可以独立更改。
如果Vehicle
发生变化,则只需更改Car
和Truck
。
如果GearShifter
发生变化,则只需要更改ManualGearShifter
和AutoGearShifter
。
由于Vehicle
(抽象)通过合成包含GearShifter
(实施),GearShifter
中的更改不会影响Vehicle
由于GearShifter
(实现者)不包含或引用Vehicle
(抽象),抽象中的更改不会影响实现。
编辑:
Bridge模式呈现两个正交的类层次结构 - 一个用于抽象,一个用于实现者,可以独立更改而不依赖于其他。
答案 2 :(得分:1)
在策略模式中,特定操作的“父级”活动是恒定的,而“子级”的活动可以变化。但是,在“桥接模式”中,父级和子级的活动可能会有所不同。
例如,
public class Ticket {
Date dateOfTravel;
int distance;
Vehicle vehicle;
Seat seat;
public float getTotalFare(){
//depends on
//Distance
//Vehicle - whether Vehicle is AC or non-AC.
//Seat - based on the location of the Seat.
//Fare = vehicleBaseFare*seatMultiplier*distance
}
}
在上面,变化取决于父级(距离)以及子级(车辆和座位)。因此,这里的Vehicle和Seat都像Bridge一样。
现在,在这里
public class Vehicle {
TrackingDevice device;
public Coordinates getCoordinates(){
return device.getCoordinates();
}
}
在这里,父母的角色是不变的,即什么也没有!因此,这是一种策略模式。