Strategy vs. Bridge Patterns

家住魔仙堡 提交于 2019-12-28 04:52:04

问题


I know this question's been asked before (e.g., What is the difference between the bridge pattern and the strategy pattern?).

However, could someone please explain, using clear-cut examples, what the difference is and in what sorts of cases one must be selected over the other? Less conceptual theory, more practical "real-life" scenarios would be appreciated.


回答1:


The Bridge Pattern makes a distinction between an abstraction and an implementation in such a way that the two can vary independently. I will use the example from

Patterns in Java, Volume 1: A Catalog of Reusable Design Patterns Illustrated with UML, Second Edition

You need to provide classes that access physical sensors such as found in scales, speed measuring devices etc. Each sensor produces a number but the number could mean different things. For the scale it could mean the weight and for the speed measuring device it may mean speed.

So you can start by creating a Sensor abstract class to represent the commonality between all sensors and various subclasses for the different types of sensors. This is a robust design allowing you to provide many more types of sensors in the future.

Now suppose that sensors are provided by different manufacturers. You will have to create a heirarchy of sensor classes for manufacturer X and another for manufacturer Y. The problem now is that the clients would need to know the difference between the manufacturers. And if you decide to support a third manufacturer...?

The solution is to provide the main abstraction heirarchy, ie. the Sensor abstract class and sub classes such as SpeedSensor and WeightSensor and so on. Then provide the interface (Bridge) that will exist between the abstraction and the implementation. So there will be a SensorInterface, WeightSensorInterface and SpeedSensorInterface, which dictates the interface that each concrete sensor class must provide. The abstraction does not know about the implementation, rather it knows about the interface. Finally, you can create an concreate implementation for each manufacturer. That is, XSensor, XWeightSensor and XSpeedSensor, YSensor, YSpeedSensor and YWeightSensor.

Clients depend only on the abstraction but any implementation could be plugged in. So in this setup, the abstraction could be changed without changing any of the concrete classes, and the implementation could be changed without worrying about the abstraction.

As you can see this describes a way to structure your classes.

The Strategy on the other hand is concerned with changing the behaviour of an object at run time. I like to use the example of a game with a character that possesses several different types of weapons. The character can attack but the behaviour of attack depends on the weapon that the character is holding at the time, and this cannot be known at compile time.

So you make the weapon behaviour pluggable and inject it into the character as needed. Hence a behavioral pattern.

These two patterns solve different problems. The strategy is concerned with making algorithms interchangeable while the Bridge is concerned with decoupling the abstraction from the inplementation so that you can provide multiple implementations for the same abstraction. That is, the bridge is concerned with entire structures.

Here are a few links that might be useful:

  1. Bridge Pattern
  2. Strategy Pattern



回答2:


I can tell this is hard to explain. Many people who use it and understand it have a hard time explaining it to newbies.

For those like me who think in terms of analogies:

Strategy Pattern

So strategy is kind-of a one-dimensional concept. Think of a one-dimensional array of strategies to choose from.

Example 1: Plumber's tools

The strategy pattern is like a plumber who has various tools to get a pipe unclogged. The job is the same each time; it's to unclog the pipe. But the tool he chooses to get this done can vary depending on the situation. Maybe he'll try one and if that doesn't work he'll try another.

In this analogy, "unclog the pipe" is the method that will implement one of the strategies. Snake brush, power auger, and draino are the concrete strategies, and the plumber is the class containing the method (labeled "Context" in most diagrams).

Example 2: Multi-bit screwdriver

Or you could think of the interchangeable bits on a multi-bit screwdriver. They are meant to be changed out at run-time to suit the job at hand, which is to screw something.

Bridge Pattern

So bridge is a two-dimensional concept. Think of one dimension (the rows) being the list of methods that need to be implemented, and the second dimension (the columns) being the Implementors who will implement each one of those methods.

Example 1: Apps and devices

The bridge pattern is like a person that has many ways that they can communicate (email, text, google voice, phone, skype) and many devices on with which they can communicate in these various ways - a PC, a tablet, and a smart phone.

The various ways to communicate (email, text, phone) would be the methods on an abstract interface, let's call it "CommunicationDevice". In this pattern, CommunicationDevice is the Implementor. Each device in this analogy (PC, tablet, smart phone) is the ConcreteImplementor that implements all these methods (email, text, phone).

Example 2: Odbc database drivers and odbc functions

Another ready example of bridge is the odbc or oledb database driver modules from Windows. They all implement the various methods on the same standard "database driver" interface, but they implement that interface in different ways. Even if you are using the same database, say Sql Server, there are still different drivers that can talk to Sql Server, albeit in different ways under the covers.

Example 3: Implementors (columns) implementing methods (rows)




回答3:


Strategy pattern

This pattern lets the algorithm that executes vary independently from the clients that use it. i.e. Instead of having a fixed algorithm to exeucte for a given sitaution, it allows one among many algorithms to be selected on-the-fly at runtime. This involves removing an algorithm from its host class and putting it in a separate class.

For example, suppose one wants to travel from a city to another, then he has several choices: take a bus, hire a car, catch a train, etc. So each mode of transport selected would transpire into a separate algorithm to be executed. The mode of transport chosen will depend on various factors decided at runtime (cost, time, etc.). In other words, the strategy chosen to execute will be decided on-the-fly.

Another example, suppose one wants to implement a SortedList class(main controller) that Sorts based on a strategy. The strategy is the method that one uses to sort (like MergeSort, QuickSort).

Comparison with the Bridge pattern

The main difference (even though both patterns have the same UML) is that unlike the bridge pattern (which is a structural pattern), the strategy pattern is a behavioral pattern. Structural patterns suggest ways in which objects are composed or associated or inherited to forms larger objects i.e. they focus on object composition. While behavioral patterns deal with the algorithm or business logic (and not on the object creation itself) i.e. they focus on the collaboration between objects.

Note that most algorithms can be implementated as static or singleton classes required only single instance creation (i.e. new is not called for everytime a strategy is set).

A closer look at the implementation of the two patterns will reveal that in the bridge pattern one creates the concrete implementation of the object and then the call.

// 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();

Whereas in the case of the strategy pattern, one will not use the concrete implementation of the algorithm directly, instead he will create the context in which the strategy should execute,

// 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();



回答4:


The Bridge pattern tells how organize classes, the Strategy - how organize algorithms.




回答5:


Both patterns separate interface from implementation. I think the key distinction is that the Bridge Pattern uses inheritance ("is a") while the Strategy Pattern uses composition ("has a").

Bridge Pattern:

class Sorter abstract
{ 
   virtual void Sort() = 0;
}

// MergeSorter IS A Sorter
class MergeSorter : public Sorter
{
   virtual void Sort() override;
}

Strategy Pattern:

class SortStrategy abstract
{
   virtual void Sort() = 0;
}

// Sorter HAS A SortStrategy
class Sorter
{ 
   Sorter(SortStragety *strategy) : mStrat(strategy) {}

   void Sort() {mStrat->Sort();}

   SortStrategy *mStrat;
}



回答6:


The Strategy pattern encapsulates algorithms so that they can be used and changed in a complex program (without gumming up the works) and the Bridge pattern allows two interfaces loosely bound so that they can interact but be changed independently of one another.

You can find PHP examples of the Bridge and Strategy patterns here:

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

and

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

You'll find a lot of examples for both patterns that may be helpful.




回答7:


Strategy:

  1. Strategy is behavioral design pattern. If is used to switch between family of algorithms.

  2. This pattern contains one abstract strategy interface and many concrete strategy implementations (algorithms) of that interface.

  3. The application uses strategy interface only. Depending in some configuration parameter, the concrete strategy will be tagged to interface.

Bridge:

  1. It allows both abstractions and implementations to vary independently.
  2. It uses composition over inheritance.
  3. Bridge is a structural pattern.

e.g. Collection classes in java.util. List implemented by ArrayList.

However, could someone please explain, using clear-cut examples, what the difference is and in what sorts of cases one must be selected over the other?

Refer to below post to get insight on use cases of Strategy and Bridge patterns:

What is the difference between the bridge pattern and the strategy pattern?

On quick note:

  1. Use Strategy pattern to dynamically change the implementation by replacing one strategy with other strategy.

    One real word example : Airlines offering discounts during off-peak months. Simply change fare discount strategy with no-discount strategy during high peak time.

  2. Use Bridge pattern when Abstractions and implementations have not been decided at compile time and can vary independently

    One real world example in Automobile industry : Different type of Gears can be assembled into different types of Cars. Both Car and Gear specification and implementation can change independently.




回答8:


Let me recite the answers from the linked question.

The bridge pattern is a structural pattern, that is, it lays out ideas of how to build a component of your project. It is used to hide two levels of abstractions. The sample code on Wikipedia (http://en.wikipedia.org/wiki/Bridge_pattern) explains it in most unambiguous terms.

The strategy pattern is a dynamic pattern. When any wild function can implement the requirements, a strategy pattern is used. Examples can be any program that allows for plugins to be developed and installed. On the Wikipedia pageg(http://en.wikipedia.org/wiki/Strategy_pattern), ConcreteStrategyAdd, ConcreteStrategySubtract, etc is plugin used in the ConcreteStrategy class. Any method could be used there that implements the interface Strategy.



来源:https://stackoverflow.com/questions/5863530/strategy-vs-bridge-patterns

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!