Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When and How Strategy pattern can be applied instead of decorator pattern?

I am learning design patterns and trying to follow Go4 book. On page:179, in the decorator pattern chapter, there is a line which says

"..by extending the number of strategies from just one to an open-ended list, we achieve the same effect as nesting decorators recursively."

I didn't quite get this statement.

Strategies focus on having independent algorithms, which can be set dynamically and don't know much about the client they are set in.

Whereas decorators are not quite independent of the clients they decorate. In fact, they are of same supertype as the object they decorate.

Am I missing a point here?

like image 617
Sandbox Avatar asked Dec 04 '10 16:12

Sandbox


People also ask

When Should Strategy Pattern be used?

Use the Strategy pattern when you want to use different variants of an algorithm within an object and be able to switch from one algorithm to another during runtime. Use the Strategy when you have a lot of similar classes that only differ in the way they execute some behavior.

What is the use of a strategy pattern give an example where it can be used?

A good example of strategy pattern would be in a game where we can have different characters and each character can have multiple weapons to attack but at a time can use only one weapon.

What is the difference between strategy and decorator pattern?

The strategy pattern allows you to change the implementation of something used at runtime. The decorator pattern allows you augment (or add to) existing functionality with additional functionality at run time.

Where is strategy pattern used?

In computer programming, the strategy pattern (also known as the policy pattern) is a behavioral software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use.


2 Answers

I'll quote a little more of the context that I think is needed for this to make sense.

Strategies are a better choice in situations where the Component class is intrinsically heavyweight, thereby making the Decorator pattern too costly to apply. In the Strategy pattern, the component forwards some of its behavior to a separate strategy object. The Strategy pattern lets us alter or extend the component's functionality by replacing the strategy object.

For example, we can support different border styles by having the component defer border-drawing to a separate Border object. The Border object is a Strategy object that encapsulates a border-drawing strategy. By extending the number of strategies from just one to an open-ended list, we achieve the same effect as nesting decorators recursively.

All this is saying is that both patterns can be used to add behavior to your base component, and that with Decorator, to add multiple behaviors, you can nest the decorators, while with Strategy, you need to use multiple strategies.

You're right that strategies are generally more independent of the main component than decorators, but it is possible for them to be aware of the component. And to use the Strategy pattern, the main component is aware of the existence of strategies, where that's not needed with Decorator.

like image 71
Don Roby Avatar answered Sep 27 '22 16:09

Don Roby


To use their example, you might have a window class which can be scrolled and/or have its border painted in various ways (or not at all). If you were to use inheritance to cover all these features, you'd need one subclass for every feasible combination of features (no border no scrolling, border without scrolling, scrolling without border, border and scrolling etc.). This is an inflexible maintenance nightmare as you add more features because there's an explosion in the number of classes.

The main point they're making here is that you can use either the strategy pattern or the decorator pattern to better solve this problem. You could have a Window class which encapsulates a scrolling strategy object and a border strategy object. Or you could take your Window object, wrap it inside a border decorator and wrap that inside a scrolling decorator.

But you're completely right in your understanding; these are two different design patterns with different characteristics which lead to different applications. With Decorator, the Component has no knowledge of the agent which is adding functionality... and so you tend to end up building around an existing component class. With Strategy, it's the other way around since the Component is employing (and hence knows about) agents to perform various tasks - these agents generally don't know about their governing Components.

like image 37
asdfjklqwer Avatar answered Sep 27 '22 18:09

asdfjklqwer