我知道之前已经问过这个问题(例如,What is the difference between the bridge pattern and the strategy pattern?)。
然而,有人可以使用明确的例子解释,区别的是什么,以及在哪种情况下必须选择另一种?更少概念理论,更实际的“现实生活”情景将不胜感激。
答案 0 :(得分:37)
Bridge Pattern以一种两者可以独立变化的方式区分抽象和实现。我将使用
中的示例Java中的模式,第1卷:使用UML,第二版说明的可重用设计模式目录
您需要提供访问物理传感器的类,例如秤,速度测量设备等。每个传感器都会产生一个数字,但数字可能意味着不同的东西。对于秤,它可能意味着重量,对于速度测量装置,它可能意味着速度。
因此,您可以从创建传感器抽象类开始,以表示所有传感器与不同类型传感器的各种子类之间的通用性。这是一种强大的设计,允许您在将来提供更多类型的传感器。
现在假设传感器由不同的制造商提供。您必须为制造商X创建传感器类的层次结构,而为制造商Y创建另一个传感器级别。现在的问题是客户需要知道制造商之间的差异。如果你决定支持第三家制造商......?
解决方案是提供主要的抽象层次,即。传感器抽象类和子类,如SpeedSensor和WeightSensor等。然后提供抽象和实现之间将存在的接口(Bridge)。因此,将有一个SensorInterface,WeightSensorInterface和SpeedSensorInterface,它们指示每个具体传感器类必须提供的接口。抽象不知道实现,而是知道接口。最后,您可以为每个制造商创建一个concreate实现。即XSensor,XWeightSensor和XSpeedSensor,YSensor,YSpeedSensor和YWeightSensor。
客户端仅依赖于抽象,但可以插入任何实现。因此,在此设置中,可以在不更改任何具体类的情况下更改抽象,并且可以在不担心抽象的情况下更改实现。
正如您所看到的,这描述了一种构建类的方法。
另一方面,策略涉及在运行时更改对象的行为。我喜欢使用具有几种不同类型武器的角色的游戏示例。角色可以攻击,但攻击行为取决于角色当时持有的武器,这在编译时无法知道。
因此,您可以将武器行为设为可插入,并根据需要将其注入角色。因此,行为模式。
这两种模式解决了不同的问题。该策略涉及使算法可互换,而Bridge涉及将抽象与实现分离,以便您可以为同一抽象提供多个实现。也就是说,桥梁与整个结构有关。
以下是一些可能有用的链接:
答案 1 :(得分:25)
我可以说这很难解释。许多使用它并理解它的人很难向新手解释它。
对于像我这样以类比的方式思考的人:
所以策略是一种一维的概念。想想一个可以选择的一维策略。
战略模式就像一名管道工,拥有各种工具来疏通管道。每次工作都是一样的;它是疏通管道的。但他选择完成这项工作的工具可能因情况而异。也许他会尝试一个,如果这不起作用,他会尝试另一个。
在这个类比中,“疏通管道”是实施其中一个策略的方法。 Snake brush,power auger和draino是具体策略,水管工是包含该方法的类(在大多数图中标记为“Context”)。
或者您可以想到多位螺丝刀上的可互换位。 它们应该在运行时更换,以适应手头的工作,这就是搞砸了。
所以桥梁是一个二维概念。可以想象一个维度(行)是需要实现的方法列表,第二个维度(列)是实现每个方法的实现者。
桥接模式就像一个人可以通过多种方式进行交流(电子邮件,文本,谷歌语音,电话,Skype)以及可以通过各种方式进行通信的许多设备 - PC,平板电脑,还有一部智能手机。
通信的各种方式(电子邮件,文本,电话)将是抽象接口上的方法,我们称之为“CommunicationDevice”。在这种模式中,CommunicationDevice是实现者。这个类比中的每个设备(PC,平板电脑,智能手机)都是ConcreteImplementor,它实现了所有这些方法(电子邮件,文本,电话)。
另一个现成的桥接示例是Windows中的odbc或oledb数据库驱动程序模块。它们都在相同的标准“数据库驱动程序”接口上实现各种方法,但它们以不同的方式实现该接口。即使你使用相同的数据库,比如Sql Server,仍然有不同的驱动程序可以与Sql Server通信,尽管有不同的方式。
答案 2 :(得分:3)
此模式允许执行的算法独立于使用它的客户端。即,不允许固定算法执行给定的sitaution,它允许在运行时中实时选择许多算法中的一个算法。这涉及从主机类中删除算法并将其放在单独的类中。
例如,假设一个人想要从一个城市旅行到另一个城市,那么他有几个选择:乘坐公共汽车,租车,搭火车等。因此,所选择的每种运输方式都会转变为单独的算法。被执行。选择的传输方式取决于运行时决定的各种因素(成本,时间等)。换句话说,选择执行的策略将在运行中决定。
另一个例子,假设有人希望基于SortedList
实现Sorts
strategy
类(主控制器)。策略是用于排序的方法(如MergeSort,QuickSort)。
主要区别(即使两种模式具有相同的UML)与桥模式(结构模式)不同,策略模式是行为模式。结构模式提出了对象被组合或关联或继承以形成更大对象的方式,即它们关注于对象组成。行为模式处理算法或业务逻辑(而不是对象创建本身),即他们专注于对象之间的协作。
请注意,大多数算法可以实现为静态或单例类,只需要创建单个实例(即每次设置策略时都不会调用new
)。
仔细研究两种模式的实现将会发现,在桥模式中,我们创建了对象的具体实现,然后是调用。
// Set implementation and call
// i.e. Returns (creates) the concrete implementation of the object,
// subsequently operation is called on the concrete implementation
ab.Implementor = new ConcreteImplementorA();
ab.Operation();
在策略模式的情况下,人们不会直接使用算法的具体实现,而是创建策略应该执行的上下文,
// Set the context with a strategy
// i.e. Sets the concrete strategy into the context, concrete implementation of the class not
// directly available as a data object (only the algorithm is available).
context = new Context (new ConcreteStrategyA());
context.contextInterface();
// Strategy can be reused instead of creating a new instance every time it is used.
// Sort example
MergeSort mergeSort = new MergeSort();
QuickSort quickSort = new QuickSort();
...
context = new Context (mergeSort);
context.Sort();
...
context = new Context (quickSort);
context.Sort();
...
context = new Context (mergeSort);
context.Sort();
答案 3 :(得分:1)
Bridge模式讲述了如何组织类,策略 - 如何组织算法。
答案 4 :(得分:1)
策略模式封装了算法,以便可以在复杂的程序中使用和更改它们(无需修改工作),并且Bridge模式允许两个接口松散绑定,以便它们可以交互但可以彼此独立地进行更改。 / p>
您可以在此处找到Bridge和Strategy模式的PHP示例:
http://www.php5dp.com/category/design-patterns/bridge/
和
http://www.php5dp.com/category/design-patterns/strategy/
您可以找到很多可能有用的模式示例。
答案 5 :(得分:1)
<强> 策略: 强>
策略是行为设计模式。如果用于在算法族之间切换。
此模式包含一个抽象策略 interface 和该接口的许多具体策略实现(算法)。
该应用程序仅使用策略 interface 。根据某些配置参数,具体策略将标记为 interface 。
<强> 桥: 强>
e.g。由java.util. List
实现的ArrayList
中的集合类。
然而,有人可以使用明确的例子解释,区别的是什么,以及在哪种情况下必须选择另一种情况?
请参阅下面的帖子,了解战略和桥梁模式的使用案例:
What is the difference between the bridge pattern and the strategy pattern?
快速记录:
使用策略模式通过将一个策略替换为其他策略来动态更改实施。
一个真实的例子:航空公司在非高峰时段提供折扣。在高峰时段,只需改变票价折扣策略,采用无折扣策略。
当抽象和实现尚未在编译时决定并且可以独立变化时,使用 Bridge 模式
汽车行业的一个真实例子:不同类型的 Gears 可以组装成不同类型的汽车。 Car 和 Gear 规范和实施都可以独立更改。
答案 6 :(得分:1)
桥接模式使我们能够根据当前情况重新实施,运行业务结构,而另一方策略模式则使我们能够实施各种业务策略并将其封装并根据情况或一次使用它们。
两者之间的主要区别是使用桥接模式可以更改整个结构,但是使用策略可以并行更改业务策略。
根据我的理解,我在下面阐述了两个非常重要的设计模式。 请仔细扔这个,我想它将清除您对它们的理解。
GoF所建议的Bridge模式将组件的实现与抽象分离开来。
让我们想象一下一种情况,其中某个组件已经实现,并且可以根据您的业务需求正常运行。突然,组织改变了他们的业务策略。为此,您需要更改或重新实现该组件。在这种情况下,您将要做的是更改过去几年运行良好的上一个组件,或者创建新组件。在这种情况下,桥接模式可以很好地处理该场景。请参见下面的示例,以更好地理解。
// Main component
public interface Ibridge
{
void function1();
}
// Already Implemented that are currently being using
public class Bridge1 : Ibridge
{
public void function1()
{
Console.WriteLine("Implemented function from bridge 1");
}
}
//New Implementation as per Organisation needs
public class Bridge2 : Ibridge
{
public void function1()
{
Console.WriteLine("Implemented function from bridge2");
}
}
//Abstract Calling functionalities
public interface IAbstractBridge
{
void CallFunc1();
}
// implementation of calling implemented component at a time
public class AbstractBridge:IAbstractBridge
{
protected Ibridge _ibridge;
public Ibridge Ibridge
{
set { _ibridge = value; }
}
public void CallFunc1()
{
this._ibridge.function1();
}
}
class Program
{
static void Main(string[] args)
{
AbstractBridge abp = new AbstractBridge();
/*
here you see that now being using the previous implemented component.
but need change newly implemented component so here we need just changed
the implementation of component, please see below
*/
//Commented old one
abp.Ibridge = new Bridge1();
//using new one just change the "Bridge1" to "Bridge2"
abp.Ibridge = new Bridge2();
abp.CallFunc1();
}
}
GoF建议的策略模式的意义是定义一系列算法,封装每个算法,并使它们可互换。策略使算法独立于使用该算法的客户端而有所不同。
让我们想象一下这样的情况:购物中心的老板希望根据客户的不同场合吸引他们提供不同折扣优惠的客户,而只要所有者可以将折扣模式从正常模式转换为正常模式,那么只要折扣价格反过来,那么如何处理这种情况在这种情况下,策略模式处理了该场景。让我们看下面的示例,以更好地理解。
public interface ISellingStrategy
{
void selling();
}
public class BasicStrategy : ISellingStrategy
{
public void selling()
{
Console.WriteLine("Buy Three get 5% discount.");
}
}
public class ChrismasStrategy : ISellingStrategy
{
public void selling()
{
Console.WriteLine("Buy Three get one offer + extra 5% discount.");
}
}
public class HoliFestiveStrategy : ISellingStrategy
{
public void selling()
{
Console.WriteLine("Buy two get one offer + extra 5% discount.");
}
}
public class DurgapuljaStrategy : ISellingStrategy
{
public void selling()
{
Console.WriteLine("Buy one get one offer + extra 5% discount.");
}
}
public class Billing
{
private ISellingStrategy strategy;
public void SetStrategy(ISellingStrategy _strategy)
{
this.strategy = _strategy;
}
public void ApplyStrategy()
{
strategy.selling();
Console.WriteLine("Please wait offer is being applying...");
Console.WriteLine("Offer is now Applied and ready for billing..");
}
}
public class BillingFactory
{
public static Billing CreateBillingObject()
{
return new Billing();
}
}
class Program
{
static void Main(string[] args)
{
Billing billing = BillingFactory.CreateBillingObject();
billing.SetStrategy(new BasicStrategy());
billing.ApplyStrategy();
Console.ReadLine();
}
}
答案 7 :(得分:0)
让我背诵相关问题的答案。
桥接模式是一种结构模式,也就是说,它阐述了如何构建项目组件的想法。它用于隐藏两个级别的抽象。维基百科上的示例代码(http://en.wikipedia.org/wiki/Bridge_pattern)用大多数明确的术语解释了它。
战略模式是一种动态模式。当任何wild函数可以实现需求时,使用策略模式。示例可以是允许开发和安装插件的任何程序。在Wikipedia pageg(http://en.wikipedia.org/wiki/Strategy_pattern)上,ConcreteStrategyAdd,ConcreteStrategySubtract等是ConcreteStrategy类中使用的插件。可以在那里使用任何实现接口策略的方法。
答案 8 :(得分:0)
两种模式都将接口与实现分开。我认为关键的区别是Bridge Pattern使用继承(“是a”)而Strategy Pattern使用了composition(“has a”)。
桥牌模式:
class Sorter abstract
{
virtual void Sort() = 0;
}
// MergeSorter IS A Sorter
class MergeSorter : public Sorter
{
virtual void Sort() override;
}
策略模式:
class SortStrategy abstract
{
virtual void Sort() = 0;
}
// Sorter HAS A SortStrategy
class Sorter
{
Sorter(SortStragety *strategy) : mStrat(strategy) {}
void Sort() {mStrat->Sort();}
SortStrategy *mStrat;
}