39

我知道以前有人问过这个问题(例如,桥模式和策略模式有什么区别?)。

但是,有人可以使用明确的示例来解释,有什么区别以及在何种情况下必须选择一个而不是另一个?更少的概念理论,更实际的“现实生活”场景将受到赞赏。

4

9 回答 9

46

桥接模式对抽象和实现进行了区分,使得两者可以独立变化。我将使用来自的示例

Java 中的模式,第 1 卷:用 UML 说明的可重用设计模式目录,第二版

您需要提供访问物理传感器的类,例如在秤、速度测量设备等中找到的传感器。每个传感器都会产生一个数字,但这个数字可能意味着不同的东西。对于秤,它可能意味着重量,对于速度测量设备,它可能意味着速度。

因此,您可以首先创建一个 Sensor 抽象类来表示所有传感器之间的共性以及不同类型传感器的各种子类。这是一个稳健的设计,允许您在未来提供更多类型的传感器。

现在假设传感器由不同的制造商提供。您必须为制造商 X 和制造商 Y 创建一个传感器类的层次结构。现在的问题是客户需要知道制造商之间的区别。如果您决定支持第三家制造商...?

解决方案是提供主要的抽象层次结构,即。Sensor 抽象类和 SpeedSensor 和 WeightSensor 等子类。然后提供将存在于抽象和实现之间的接口(桥)。所以会有一个 SensorInterface、WeightSensorInterface 和 SpeedSensorInterface,它们规定了每个具体的传感器类必须提供的接口。抽象不知道实现,而是知道接口。最后,您可以为每个制造商创建一个 concreate 实现。即 XSensor、XWeightSensor 和 XSpeedSensor、YSensor、YSpeedSensor 和 YWeightSensor。

客户端只依赖于抽象,但可以插入任何实现。因此在此设置中,可以在不更改任何具体类的情况下更改抽象,并且可以更改实现而不用担心抽象。

如您所见,这描述了一种构建类的方法。

另一方面,策略关注的是在运行时改变对象的行为。我喜欢使用一个角色拥有几种不同类型武器的游戏示例。角色可以攻击,但攻击的行为取决于角色当时持有的武器,这在编译时无法得知。

因此,您可以使武器行为可插入,并根据需要将其注入角色中。因此,行为模式。

这两种模式解决了不同的问题。该策略关注于使算法可互换,而 Bridge 关注于将抽象与实现分离,以便您可以为同一个抽象提供多个实现。也就是说,桥与整个结构有关。

以下是一些可能有用的链接:

  1. 桥接模式
  2. 策略模式
于 2011-05-03T03:06:58.943 回答
35

我可以说这很难解释。许多使用它并理解它的人很难向新手解释它。

对于像我这样以类比方式思考的人:

策略模式

所以战略是一种一维的概念。考虑一个可供选择的一维策略数组。

示例 1:管道工的工具

策略模式就像一个管道工,他拥有各种工具来疏通管道。每次工作都是一样的;这是为了疏通管道。但他选择完成这项工作的工具可能会因情况而异。也许他会尝试一个,如果这不起作用,他会尝试另一个。

在这个类比中,“疏通管道”是实现策略之一的方法。Snake Brush、Power Auger 和 Draino 是具体的策略,而水管工是包含该方法的类(在大多数图中标记为“上下文”)。

在此处输入图像描述

示例 2:多头螺丝刀

或者您可以想到多位螺丝刀上的可互换位。它们旨在在运行时进行更改以适应手头的工作,即搞砸一些东西。

在此处输入图像描述

桥接模式

所以桥是一个二维的概念。考虑一维(行)是需要实现的方法列表,第二维(列)是将实现这些方法中的每一个的实施者。

示例 1:应用程序和设备

桥接模式就像一个人可以通过多种方式进行交流(电子邮件、文本、谷歌语音、电话、Skype)和许多可以通过这些方式进行交流的设备——PC、平板电脑和智能手机电话。

各种通信方式(电子邮件、文本、电话)将是抽象接口上的方法,我们称之为“CommunicationDevice”。在此模式中,CommunicationDevice 是实现者。这个类比中的每个设备(PC、平板电脑、智能手机)都是实现所有这些方法(电子邮件、文本、电话)的 ConcreteImplementor。

在此处输入图像描述

示例 2:odbc 数据库驱动程序和 odbc 函数

另一个现成的桥接示例是 Windows 的 odbc 或 oledb 数据库驱动程序模块。它们都在相同的标准“数据库驱动程序”接口上实现了各种方法,但它们以不同的方式实现该接口。即使您使用的是同一个数据库,比如 Sql Server,仍然有不同的驱动程序可以与 Sql Server 通信,尽管在幕后以不同的方式。

示例 3:实现者(列)实现方法(行)

实现者(列)实现方法(行)

于 2015-04-09T17:58:14.267 回答
4

策略模式

这种模式允许执行的算法独立于使用它的客户端而变化。即,它允许在运行时动态选择许多算法中的一种,而不是使用固定算法来执行给定的情况。这涉及从其宿主类中删除算法并将其放入单独的类中。

例如,假设一个人想从一个城市旅行到另一个城市,那么他有几个选择:乘坐公共汽车、租车、搭乘火车等。因此,选择的每种交通方式都会演变成一个单独的算法来执行。选择的运输方式将取决于运行时决定的各种因素(成本、时间等)。换句话说,选择执行的策略将即时决定。

另一个例子,假设一个人想要实现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();
于 2011-05-03T01:08:07.460 回答
3

桥模式告诉如何组织类,策略——如何组织算法。

于 2013-09-04T12:25:31.180 回答
2

桥接模式和策略模式的区别:

桥接模式使我们能够重新实施,根据我们当前的情况运行业务结构,对方策略模式使我们能够实施我们的各种业务策略并将它们封装起来并根据情况或一次使用它们。

两者之间的主要区别在于使用桥接模式我们可以改变我们的整体结构,但使用策略我们可以同时改变我们的业务策略。

根据我的理解,我在下面详细阐述了两个非常重要的设计模式。请小心扔掉这个我想它会清除你对它们的理解。


桥接模式:

什么是桥接设计模式?

GoF 建议的桥模式的意义是将组件的实现与其抽象分离。

我们什么时候会使用桥接设计模式?

让我们想象一个组件已经实现的情况,并且它根据您的业务需求运行良好。突然,该组织改变了他们的商业战略。为此,您需要更改或重新实现组件。在这种情况下,您将做什么改变过去几年运行良好的前一个组件,或者您创建新组件。在这种情况下,桥模式很好地处理了这个场景。请参阅下面的示例以更好地理解。

// 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();
    }
}
于 2020-03-24T06:52:25.663 回答
1

两种模式都将接口与实现分开。我认为关键的区别在于桥模式使用继承(“is a”),而策略模式使用组合(“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;
}
于 2013-12-11T22:50:37.220 回答
1

策略模式封装了算法,以便它们可以在一个复杂的程序中使用和更改(不会弄乱工作),而桥接模式允许两个接口松散绑定,以便它们可以交互但可以相互独立地更改。

您可以在此处找到 Bridge 和 Strategy 模式的 PHP 示例:

http://www.php5dp.com/category/design-patterns/bridge/

http://www.php5dp.com/category/design-patterns/strategy/

您会发现很多可能对这两种模式都有帮助的示例。

于 2014-07-30T09:54:14.823 回答
1

战略:

  1. 策略是行为设计​​模式。If 用于在算法族之间切换。

  2. 该模式包含一个抽象策略接口和该接口的许多具体策略实现(算法)。

  3. 该应用程序仅使用策略接口。根据某些配置参数,具体策略将被标记为interface

桥:

  1. 它允许抽象和实现独立变化
  2. 它使用组合而不是继承。
  3. 桥梁是一种结构模式

但是,有人可以使用明确的示例来解释,有什么区别以及在何种情况下必须选择一个而不是另一个?

请参阅以下帖子以深入了解策略和桥接模式的用例:

策略模式的真实示例

什么时候使用桥接模式?它与适配器模式有何不同?

快速说明:

  1. 使用策略模式通过将一种策略替换为另一种策略来动态更改实现。

    一个真实的例子:航空公司在非高峰月份提供折扣。只需在高峰时段将票价折扣策略更改为无折扣策略。

  2. 当抽象和实现尚未在编译时确定并且可以独立变化时使用桥接模式

汽车行业的一个真实例子:不同类型的齿轮可以组装成不同类型的汽车CarGear规范和实现都可以独立更改。

于 2016-02-04T17:24:54.920 回答
0

让我背诵链接问题的答案。

桥接模式是一种结构模式,也就是说,它列出了如何构建项目组件的想法。它用于隐藏两个抽象级别。Wikipedia (http://en.wikipedia.org/wiki/Bridge_pattern) 上的示例代码用最明确的术语解释了它。

策略模式是一种动态模式。当任何野函数都可以实现需求时,就会使用策略模式。示例可以是任何允许开发和安装插件的程序。在 Wikipedia pageg(http://en.wikipedia.org/wiki/Strategy_pattern) 上,ConcreteStrategyAdd、ConcreteStrategySubtract 等是用于 ConcreteStrategy 类的插件。任何实现接口策略的方法都可以在那里使用。

于 2011-05-03T00:00:12.213 回答