15

When applying a comparator to a list in the following manner, what is the design pattern being used or what is the technique being used here?

Collections.sort(myCollection, new Comparator<MyItem>() {

    @Override
    public int compare(MyItem item1, MyItem item2) {
        return item1.getId().compareTo(item2.getId());
    }

});
cellepo
  • 4,001
  • 2
  • 38
  • 57
Dinesh Kumar
  • 307
  • 1
  • 3
  • 9
  • 19
    [Strategy](https://en.wikipedia.org/wiki/Strategy_pattern). – Andy Turner Feb 24 '17 at 15:11
  • @AndyTurner I don't think there is any *design-pattern* being used her per-se. This is your regular grade *polymorphism* in action. The very link that you shared defines the [structure](https://en.wikipedia.org/wiki/Strategy_pattern#Structure) of the *Strategy Pattern* with an *interface* and some concrete implementations. – Chetan Kinger Feb 24 '17 at 15:51
  • @CKing can you think of a behavioral design pattern which isn't "your regular grade polymorphism in action"? – Andy Turner Feb 24 '17 at 15:57
  • @AndyTurner A design pattern builds on top of the concepts such as *polymorphism* and *inheritance*. The *Strategy Pattern* has a well defined structure. The terms *Strategy Pattern* and *polymorphism* should not be interchangable. – Chetan Kinger Feb 24 '17 at 16:00
  • "The Strategy Pattern has a well defined structure" and what is that? – Andy Turner Feb 24 '17 at 16:01
  • @AndyTurner [Structure](https://en.wikipedia.org/wiki/Strategy_pattern#Structure) – Chetan Kinger Feb 24 '17 at 16:07
  • And what's the difference between the `execute()` method there, and the `compare()` method in a comparator? – Andy Turner Feb 24 '17 at 16:09
  • @AndyTurner There is a subtle difference. `CalculateClient` *has-a* `ICalculate`. This is known as the `Context` in the strategy pattern. A class that establishes a *has-a* relationship with the Strategy implementations. – Chetan Kinger Feb 24 '17 at 16:12
  • @CKing I think that we disagree on the interpretation of "context in which they operate" that you quote below. I don't see that as necessarily meaning that there is a Context object; as in, a method has-a strategy instance, if it was passed as a method parameter; saying that it's only strategy if you read the strategy from a field just feels like an implementation detail which doesn't really change the nature of the pattern. But I can see that we're just going to have to agree to disagree; rest assured that I wasn't the DV of your answer. – Andy Turner Feb 24 '17 at 16:44
  • 1
    @AndyTurner Eric Gamma of GoF fame says *Object composition offers a potentially more workable and flexible extension mechanism* when he talks about the Strategy pattern. Object composition is a key to the definition of the *Strategy pattern*. I wish I could agree to disagree but I can't since there is a subtle but clear difference when it comes to *polymorphism* and the strategy pattern. A pattern uses the basic building blocks provided by the language. It is not interchangeable with these blocks. – Chetan Kinger Feb 24 '17 at 16:55

3 Answers3

14

TL;DR :

Collections.sort is an example of a simple polymorphic substitution regardless of whether you use Functional Programming or Object Oriented Programming to make this substitution. The term Strategy Pattern is not interchangeable with Polymorphism or Functional Programming.

One could still say that we are passing a sorting Strategy to the sort method but without the Context, it is not synonymous to the Strategy Pattern.


When applying a comparator to a list in the following manner, what is the design pattern being used or what is the technique being used here?

Since this question has been tagged as OOP, there is no OOP design-pattern being used here per-se. This is plain old Polymorphism in action. Some programmers may call this the Strategy Pattern but I disagree. The Strategy pattern advocates Composition over Inheritiance where you use a has-a relationship rather than an is-a relationship.

Some programmers may further argue that we are passing a sorting Strategy to the Collections.sort method so this is the Strategy Pattern; however, what one needs to acknowledge is that Strategy is one of the components of the Strategy Pattern. The other important component of the Strategy pattern is its Context that establish a HAS-A relationship with the Strategy. This component is central to the motivation behind the Strategy Pattern which is to prefer composition over inheritance. You can't take a part out of the whole and still call that separated part a whole. You can't take the Context out of the Strategy Pattern and still call the remainder the Strategy Pattern.

Collections.sort is a static method that is allowing you to Polymorphically substitute the Comparator implementation to be used at runtime.


Supporting material

Let's take a look at the definition of Strategy Pattern from GoF :

Encapsulating an algorithm in an object is the intent of the Strategy ( 315) pattern. The key participants in the pattern are Strategy objects (which encapsulate different algorithms) and the context in which they operate. Compositors are strategies; they encapsulate different formatting algorithms. A composition is the context for a compositor strategy.

....

Object composition offers a potentially more workable and flexible extension mechanism..

It should now be clear that there is a subtle difference between Polymorphism and the Strategy Pattern. The Strategy pattern talks about a Context that uses composition as highlighted in bold above. The Collections class does not establish a composition relationship with the Comparator. Furthermore, the class diagram for the Strategy Pattern shows a component called the Context which composes the Strategy interface.

This question was tagged as OOP but if we want to talk about what pattern would Collections.sort represent when it comes to the functional programming paradigm, I would say it represents functional programming. (If I had to equate passing a function to a method to an OOP pattern, I would say it closely (not completely) resembles the Command Pattern more than the Strategy Pattern)

Related content : Does Functional Programming Replace GoF Design Patterns?

Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82
  • Comments are not for extended discussion; this conversation has been [moved to chat](http://chat.stackoverflow.com/rooms/136674/discussion-on-answer-by-cking-whats-design-pattern-does-collections-sort-with-a). – Bhargav Rao Feb 26 '17 at 14:07
  • 1
    The most concise statement is on page 316, "_Strategies provide a way to configure a class..._" If strategies provided a way to configure a method, the book would say so. (I tend towards the perspective of [textualism](https://en.wikipedia.org/wiki/Textualism) when interpreting the GoF.) – jaco0646 Nov 01 '18 at 14:18
7

Collections.sort() uses Strategy pattern.

Pmakari
  • 264
  • 5
  • 13
  • 1
    I would disagree. Strategy pattern has a well defined structure which Collection.sort doesn't use. The strategy pattern advocates composition over inheritance. *Strategy pattern* and *Polymorphism* are not interchangeable terminologies. – Chetan Kinger Feb 24 '17 at 16:42
  • @ChetanKinger - what is more important when recognizing which pattern is used / is to be used: implementation or intent? Strategies intent is: pass part of an algorithm (comparison logic) to another (sort) thus proving DRY implementation of a method where the main algorithm can be reused. In java it was only possible to do via object as it never supported higher order functions. Functional strategy pattern makes this simple - you simply pass a function. Strategy in OOP - you must encapsulate the logic into an object. Simple and elegant explanation your literalism notwithstanding. – Mindaugas Bernatavičius Jul 08 '22 at 10:32
2

I think it would be better to look at first another form of

Collections.sort(myCollection)

Which does not get any Algorithm to compare items at run-time. In this approach it uses the Algorithm which is provided by inheritance for Items (by implementing Comparable interface). Not in an straight forward way but if we look at this a little flexible, this is Template Pattern. This approach uses inheritance and behavior of items can not change at run time.

But in second form of

Collections.sort(myCollection, comparing-algorithm)

We send the behavior at run-time unlike Template Pattern (Inheritance) which is possible when we use run-time provided and changeable behaviors. Which is the most important part of Strategy Pattern.

Someone may ask where is the Composition part of Strategy Pattern here? Composition is nothing just to hold the Algorithm so that it is used whenever it is required. But in this case whenever the algorithm is required it is passed as an argument because Collections class is a Utils class which is used for different purposes, not the Context class we see in Original version of Strategy Pattern.

hyeganeh
  • 348
  • 2
  • 11
  • Dynamic dispatch and runtime polymorphism are well established features/constructs of every OO language. Object Oriented Design patterns build on top of these language features/constructs. Saying that dynamic dispatch is like the Template pattern or Polymorphic substitutions in method parameters is the same as the Strategy pattern is counterproductive and counterintuitive. The strength of design patterns is in their communication. If we start equating every language feature/construct to a design pattrrn, we create confusion and render these patterns useless. – Chetan Kinger Nov 16 '17 at 03:42