2

More and more I see new labels for the same solutions but with different names. In this case why we cannot simply say that the Execute Aroud idiom is the same that the Strategy design pattern?

When I read the Jon Skeet’s answer to the question: “What is the “Execute Around” idiom?”, he states that:

it's the pattern where you write a method to do things which are always required, e.g. resource allocation and clean-up, and make the caller pass in "what we want to do with the resource".

In this case @jon-skeet uses a executeWithFile(String filename, InputStreamAction action) method as an example of the method that does things which are always required and the interface InputStreamAction as an abstraction over what we want to do with the resource.

  public interface InputStreamAction
  {
      void useStream(InputStream stream) throws IOException;
  }

Comparing this with the Stratey design pattern why we cannot just say that the interface InputStreamAction defines a family of algorithms? And, each implementation of the interface InputStreamAction corresponds to a concrete strategy encapsulating an algorithm. Finally these algorithms are interchangeable and we can make use of the executeWithFile with any of those strategies.

So, why can’t I interpret the Jon Skeet’s answer as an example of the application of the Stratey design pattern?

By the way, which of the idioms came first? The Execute Around or the Strategy design pattern?

Although the Execute Around idiom is usually related with a functional style programming, the only documentation that I found about it was in Smalltalk Best Practice Patterns book from 1997 in the scope of the Smalltalk programming language, which follows an OO approach.

Because Design patterns describe general solutions to recurrent problems, then we can say that the Execute Around and Strategy are both the same solution to solve different problems. So, I ask: do we really need a different name to identify the same solution, when it is applied to a different problem?

Although I agree with @iluwatar's answer that this is the way to communicate different ideas, I still think that I could transmit the idea of the Execute Around just telling that: "I used a Strategy to specify what I want to do with a resource, which is always setup and cleaned in the same manner."

So the Execute Around idiom is reducing ambiguity (and that's good), but at same time is proliferating the names of design patterns? And, is that a good practice?

Community
  • 1
  • 1
Miguel Gamboa
  • 8,855
  • 7
  • 47
  • 94

3 Answers3

3

While Strategy and Execute Around are technically very similar they communicate different ideas. When we discuss interchangeable algorithms the term to use is Strategy. When we discuss about allocating and freeing resources around a business method we should use the term Execute Around.

iluwatar
  • 1,778
  • 1
  • 12
  • 22
  • I don’t think that this comparison is similar with the debate between State vs Strategy patterns. First, the State and Strategy are both well documented design patterns included in the book of [Eric Gamma et al]( http://en.wikipedia.org/wiki/Design_Patterns). The Execute Around is not documented. Second, a Context provides a complete functionality with a concrete Strategy, such as the Execute Around that provides a complete functionality with a concrete Action. On the other hand, in the State Design Pattern the Context depends of several concrete States. – Miguel Gamboa Mar 20 '15 at 18:40
  • IMHO Execute Around idiom is a good and useful addition to our patterns. My main point being that when designers discuss code structure Execute Around communicates something entirely different than Strategy and that is useful. – iluwatar Mar 20 '15 at 19:41
  • Ok, I agree with your opinion that “Execute Around **communicates** something entirely different than Strategy”. From a semantics point of view they are used in different contexts. Regarding that a Design Pattern is described by several attributes, including: Name, Classification, Goal, Structure, etc., and also a **Context** that let programmers identify a **problem** where they can apply a certain Design Pattern. In that sense, although the Execute Around and the Strategy share a solution with the **same Structure** they are applied in **different Contexts**. – Miguel Gamboa Mar 21 '15 at 12:25
  • Yet, I continue to disagree with your comparison with the debate around State vs Strategy. In the State pattern the Context depends on **several concrete states**, whereas in Strategy the Context just depends of **only one concrete strategy**. Moreover, in the Strategy pattern the Client may provide a concrete strategy that is unknown by the Context, whereas in the State pattern the Context may know the concrete states beforehand. So I would suggest that you remove the reference to the State from your answer. And, maybe you could complete your answer with what each pattern **communicates**. – Miguel Gamboa Mar 21 '15 at 12:35
  • Thank you for the suggestions. I edited the answer according to your comments. – iluwatar Mar 21 '15 at 13:04
3

The way I see it, although both may be solutions to similar problems, these are different idioms and, therefore, should have different names.

I call them idioms, because the execute around it's just a programming idiom, used in many typical situations (similar to one presented) and also in several languages. And, at least that I have knowledge, the Execute Around was never formalized as a software design pattern, at least yet.

And why are they different? Here's my view:
The Stategy design pattern is intended to (from Wikipedia):

  • defines a family of algorithms,
  • encapsulates each algorithm, and
  • makes the algorithms interchangeable within that family.

Typically the strategy instance as a long lasting relation with the context instance, typically passed as a constructor dependency. Even though the context may have setters to the strategy, the same strategy can be used in several call to the context, without the caller (client) even not knowing which one is being used by that particular context and at the moment the call was done. Moreover, the same strategy instance may be used by the context in several methods of its public interface, without the caller no even knowing anything about its usage.

On the other hand, the execute around idiom is suited for parameterized algorithms, where the caller (client) should always pass the algorithm parametrization function in each call. Therefore, the strategy function passed, only influences behavior of that particular call, not other calls.

Although the presented differences may seam theoretical and rhetorical, if you put the context being called in a multithreaded scenario, is where I think the differences are more obvious and easily seen and "felt".

Without lots of locks and synchronization, you cannot use the strategy design pattern in a multithreaded scenario, at least if it is allowed to change the context strategy. If you don't, you see the more lasting duration of that relation between the context and the strategy, as they typically live the same time.

The execute around idiom, if properly implemented, should not suffer from this "disease", at least if the the passed function doesn't have any side effects.

Wrapping up, although Strategy design pattern and execute around idiom may seam alike, may be used to solve similar problems, and may seam to have a similar static structure, they are different in nature, having the former a much more OO style and the latter more functional style and, therefore, should have different names!

I agree with Miguel Gamboa, that the proliferation of names that mean the same is not good and should be avoided. But, at least in my opinion, this is not the case.

Hope this helps!

  • I think that you put very clearly the main difference between these two idioms. And now I think that my misunderstanding came from the fact that some authors relate the Strategy design pattern with something that is not really a Strategy, such as the method _filter_: `List filter(List itens, Predicate p)` that is pointed in the [Java 8 in Action]( https://github.com/java8/Java8InAction) to be related with the Strategy design pattern. And, according to your view this would be not an application of the Strategy design pattern. – Miguel Gamboa Mar 22 '15 at 22:21
1

To me, the Strategy pattern being a "family of algorithms" implies that there are multiple different ways to achieve a particular goal. For example, there are multiple different algorithms/strategies that can achieve the particular goal of sorting a list of values. But in the example given – where executeWithFile handles the opening and closing of a file – I don't think that there is any particular goal for the InputStreamAction family. The concrete implementations probably all have different goals.

In Java, the Execute Around pattern requires objects that are concrete implementations of interfaces. I think that's why it looks so similar to the Strategy pattern. But in other languages, only a plain old function is required. Take Ruby, for example:

execute_with_file('whatever.txt') do |stream|
   stream.write('whatever')
end

There is no InputStreamAction interface, and there is no concrete WhateverWriterAction. There is just a function that takes a another function as a parameter. Can a plain old function parameter be considered as a "strategy"? It could be, but I wouldn't call it a strategy. And I certainly don't think of it in terms of the Strategy pattern when I'm using or creating an Execute Around implementation.

In summary, if you wanted to be very literal, you could say that Execute Around is a specific type of Strategy pattern. If you consider the intent behind the two patterns, however, they are separate ideas: the Strategy pattern is a family of algorithms that achieve a particular goal, and Execute Around is a generic way to run something before and after a chunk of arbitrary code.

Tom Dalling
  • 23,305
  • 6
  • 62
  • 80
  • Note that since Java 8 you can also pass functions as parameters to other functions. – Miguel Gamboa Mar 22 '15 at 10:20
  • That’s a very interesting observation that helps to understand the existence of the two terms. Are you telling that the genesis of the Execute Around came from functional languages? (in opposition to the Strategy that is well-known in the oop field) Can you give a reference about the Execute Around idiom/pattern? – Miguel Gamboa Mar 22 '15 at 10:20
  • 1
    I don't know for sure, but it sounds reasonable that Execute Around comes from languages with first-class functions. It's a very natural way to write code in those languages. So natural, in fact, that even though I knew exactly what it was, I'd never actually heard a name for it until I read your question, so I can't really point you to any reference material better than google can. – Tom Dalling Mar 23 '15 at 02:46
  • I am not sure either if this is the first documentation about the Execute Around idiom but I found it in this book from 1997 in the scope of Smalltalk that is OO: http://books.google.pt/books/about/Smalltalk_Best_Practice_Patterns.html?id=PQx2QgAACAAJ – Miguel Gamboa Mar 23 '15 at 10:00