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());
}
});
Strategy Design Pattern Important Points Same is followed in Collections. sort() and Arrays. sort() method that take comparator as argument. Strategy Pattern is very similar to State Pattern.
The Collections. sort has two overloaded methods : public static void sort(List list): Sort the list into ascending order, the natural ordering of its element. public static void sort(List list, Comparator c): Sort the list according to the specified comparator.
Strategy Pattern One of the best examples of this pattern is the Collections. sort() method that takes the Comparator parameter. Based on the different implementations of Comparator interfaces, the Objects are getting sorted in different ways.
How does the Sort Method in the Collection Sort Work? Whenever we need to sort the values in a collection, this “sort” method transfers control to the compare method in the class. The compare method then returns some values based on the comparison. It returns 0 if both the objects are equal.
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?
Collections.sort() uses Strategy pattern.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With