桥梁模式和战略模式的区别是什么?

我试着在 工厂、维基百科和许多网站上阅读许多文章。 我不知道桥梁模式和战略模式的区别。

我知道它们都将抽象与其实现分离,并且可以在运行时更改实现。

但是我仍然不知道在什么情况下我应该使用策略,或者在什么情况下我应该使用桥牌。

47035 次浏览

从维基的 策略模式

策略的 UML 类图 模式与图表相同 但是,这两个 设计模式是不一样的 他们的意图。而战略 模式是为行为准备的 桥式图案是用来构造的。

上下文与 这些策略比 抽象与 桥中的实施 模式。

语义学,来自 维基百科:

策略的 UML 类图 模式与图表相同 但是,这两个 设计模式是不一样的 他们的意图。而战略 模式是为行为准备的 桥式图案是用来构造的。

上下文与 这些策略比 抽象与 桥中的实施 模式。

据我所知,当你抽象可以从外部源提供的行为(例如 config 可以指定加载一些插件程序集)时,你就是在使用策略模式,当你使用相同的结构来使代码更简洁时,你就是在使用桥模式。实际的代码看起来非常相似——您只是应用了 有点不同的原因的模式。

在实现上,它们可以是一样的。然而,您使用策略来交换策略,比如排序策略,而使用桥接器来连接两个对象的实现,比如数据库包装器和网络适配器,这样客户端代码可以使用其中一种来处理相同的 API。所以命名实际上说明了一切

大桥模式是一种结构模式(如何建造基于组件的软件工程?).策略模式是一种动态模式(您希望如何在软件中运行行为?).

语法相似,但目标不同:

  • Strategy : 你有更多的方法来执行一个操作; 使用 Strategy,你可以在运行时选择算法,你可以在编译时修改一个 Strategy 而不会产生很多副作用;
  • Bridge : 您可以分割接口和类的层次结构,使用一个抽象引用将其连接起来(参见 解释)

只是为了补充已经说过的关于模式比较的内容(意图的差异,...) : 桥模式也是有意构造的,以允许抽象层次结构方面的变化。在像 C # 这样的语言中,这可能意味着您拥有一个包含虚方法的抽象基础,作为一种允许预期变化的方式,这些变化不会对现有的使用者造成问题。除此之外,这两种模式在大多数情况下可能是相同的。

策略:

  • 与策略相关的上下文: 上下文类(可能是抽象的,但不是真正的接口!)!因为您希望封装出一个特定的行为,而不是整个实现)将知道/包含策略接口引用和 实施来调用它上面的策略行为。
  • 意图是在运行时交换行为的能力

    class Context {
    
    
    IStrategy strategyReference;
    
    
    void strategicBehaviour() {
    
    
    strategyReference.behave();
    }
    
    
    }
    

Bridge

  • Abstraction not tied to the Implementation: The abstraction interface (or abstract class with most of the behavior abstract) would not know/contain the implementation interface reference
  • Intent is to completely decouple the Abstraction from the Implementation

    interface IAbstraction {
    
    
    void behaviour1();
    
    
    .....
    
    
    }
    
    
    interface IImplementation {
    
    
    void behave1();
    
    
    void behave2();
    
    
    .....
    
    
    }
    
    
    class ConcreteAbstraction1 implements IAbstraction {
    
    
    IImplementation implmentReference;
    
    
    ConcreteAbstraction1() {
    
    
    implmentReference = new ImplementationA() // Some implementation
    
    
    }
    
    
    void behaviour1() {
    
    
    implmentReference.behave1();
    
    
    }
    
    
    .............
    
    
    }
    
    
    class ConcreteAbstraction2 implements IAbstraction {
    
    
    IImplementation implmentReference;
    
    
    ConcreteAbstraction1() {
    
    
    implmentReference = new ImplementationB() // Some Other implementation
    
    
    }
    
    
    void behaviour1() {
    
    
    implmentReference.behave2();
    
    
    }
    
    
    .............
    
    
    }
    

当您希望在运行时插入算法或策略时,可以使用策略模式。作为范畴的模式也意味着它处理对象的行为。另一方面,桥梁是结构模式,处理对象的结构层次。它通过在抽象和实现之间引入一个精确的抽象来解耦抽象和实现。精确的抽象可能与运行时策略(在策略模式中)混淆。桥模式通过提供一种避免创建 n 个类的机制来处理结构方面的问题。

桥梁(一种结构模式)

桥模式将抽象和实现解耦,并允许两者独立变化。

在以下情况下使用这种模式:

  1. 在编译时还没有确定抽象和实现
  2. 抽象和实现应该独立地进行更改
  3. 抽象实现的更改不应该影响调用方应用程序
  4. 客户端应该与实现细节隔离。

策略: (行为模式)

策略模式允许您在运行时从一系列算法中切换多个算法。

在以下情况下使用策略模式:

  1. 需要多个版本的算法
  2. 类的行为必须在运行时动态更改
  3. 避免使用条件语句

相关职位:

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

战略模式的真实世界范例

我也是这么想的,但是最近我不得不使用 bridge,并且意识到 bridge 是在使用策略,在上下文中添加抽象,这样以后你就可以在不改变客户端的情况下做出更多的改变。如果没有抽象地使用 Strategy,设计就没有那么灵活,可能需要以后对客户进行更改。但是,当使用整个桥梁的设计变得更加灵活。在这里,您可以看到从 Strategy 到 Bridge 如何提供更大的灵活性。此外,我们假设现在“ Visa”和“ master”不仅可以在卡片上使用,还可以在手机和芯片上使用; 如果我们使用 bridge,添加这种支持就会容易得多。

Strategy VS Bridge

  1. 策略 模式用于行为决策,而 舰桥模式用于结构决策。

  2. Brigde 模式将抽象元素从实现细节中分离出来,而 策略模式则致力于使算法更具可互换性。

UML 中的策略模式

UML 中的旅模式

Swift 中的战略模式:

protocol PrintStrategy {
func print(_ string: String) -> String
}


class Printer {
let strategy: PrintStrategy


init(strategy: PrintStrategy) {
self.strategy = strategy
}


func print(_ string: String) -> String {
return self.strategy.print(string)
}
}


class UpperCaseStrategy: PrintStrategy {
internal func print(_ string: String) -> String {
return string.uppercased()
}
}


class LowerCaseStrategy: PrintStrategy {
internal func print(_ string: String) -> String {
return string.lowercased()
}
}


var lower = Printer(strategy: LowerCaseStrategy())
lower.print("I love Software Patterns")


var upper = Printer(strategy: UpperCaseStrategy())
upper.print("I love Software Patterns")

斯威夫特中的旅模式:

protocol Appliance {
func run()
}


protocol Switch {
let appliance: Appliance {get set}
func turnOn()
}


class RemoteControl: Switch {
var appliance: Appliance


init(appliance: Appliance) {
self.appliance = appliance
}


internal func turnOn() {
appliance.run()
}
}


class TV: Appliance {
internal func run() {
print("TV is ON")
}
}


class Stereo: Appliance {
internal func run() {
print("Stereo is ON")
}
}


var tvRemote = RemoteControl.init(appliance: TV())
tvRemote.turnOn()


var stereoRemote = RemoteControl.init(appliance: Stereo())
stereoRemote.turnOn()

对于策略模式,只有实现是不同的。

假设类 A 使用具有多个可用实现的类 B。所以在这种情况下,B 是抽象的,实际的实现是在运行时提供的。这是战略模式

现在如果 A 本身是抽象的,那么 A 和 B 都可以变化,你可以使用桥模式。

我认为它们之间在使用的环境上有细微的差别。

我使用桥模式来分离正交的概念,它们都属于一个更大的概念-让它们独立地变化。它通常涉及多个抽象。

在国际海事组织看来,战略模式更简单或更平面。它肯定服务于 OCP,但不一定是另一个更大的概念,如桥模式的一部分。

设计模式类型

  • 行为: 模式描述了类或对象交互和分配责任的方式
  • 结构化: 模式处理类或对象的组合。
  • Creational: 模式关注对象创建的过程。

桥梁(结构)

将抽象与其实现解耦,以便每个抽象都可能有所不同。 独立的。 enter image description here

拿个遥控器。遥控器上有1-6个按钮。这是上图中的具体类。每个按钮的工作方式都不同,这取决于遥控器是用于电视还是 DVD。每个按钮的功能都是通过实现者接口从实现中抽象出来的。

这允许我们改变遥控器在每个设备上的工作方式。

策略 (行为)

定义一系列算法,封装每个算法并使它们可以互换。 enter image description here

在策略上,如果我们考虑远程场景。“状态”是我们通过更改上下文的状态引用来交换的整个远程。“ concreteStateA”(电视遥控器)“ concreteStateB”(DVD 遥控器)。

补充阅读:

在策略模式中,特定操作的“父母”的活动是恒定的,而“孩子”的活动可以变化。然而,在桥模式中,父母和孩子的活动是可以变化的。

比如说,

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


}
    

}

在上述情况下,变化取决于父母(距离)以及子女(车辆和座位)。所以,这里的车辆和座位,都扮演桥梁。

给你

public class Vehicle {


TrackingDevice device;


public Coordinates getCoordinates(){
return device.getCoordinates();
}
}

在这里,父母的角色是恒定的,也就是说,什么也没有! 所以,这是一个策略模式。

除了其他回答者解释的用例差异之外,还有其他需要考虑的事情。

看起来 BridgeStrategyTemplate method行为模式的结合。因此,我们按照与 Template method相同的顺序调用方法,并根据给定的实现者改变其行为,就像在 Strategy模式中一样。< br > < br > 这难道不意味着两种行为模式共同创造了一种结构模式吗?我们可以使用 Bridge模式的行为方式?