After Java 8, this controversy is often seen about saying that some classic patterns have become obsolete. A pattern codifies what is considered best practice for one type of problem, but not every practice is eternally the best and can be replaced or constantly perfected. It is still important to know the problems that each pattern proposes to solve, even if an improvement in implementation is possible.
The Gang of Four itself considers that the chosen programming language influences how the pattern will be implemented, being easier or more difficult depending on the features that the language offers: " In (See Iterator for example.) "
The Java 8 Lambda: Pragmatic Functional Programming book describes some of the improved patterns in Java 8. For example, the Observer simpler, can dispense with the implementation of classes that implement the interface that defines an observer. These classes are replaced by Java 8 functions. The pattern has been greatly simplified, but the problem still exists and the pattern too.
To illustrate simplification in the Observer pattern, consider the following interface to be implemented by organizations that wish to observe who lands on the moon. In this example, aliens and NASA will be observers.
public interface LandingObserver {
public void observeLanding(String name);
}
The subject is the Moon:
public class Moon {
private final List<LandingObserver> observers = new ArrayList<>();
public void land(String name) {
for(LandingObserver observer : observers) {
observer.observeLanding(name);
}
}
public void startSpying(LandingObserver observer) {
observers.add(observer);
}
}
Following are the implementations of the observers who represent the aliens and Nasa and who respond to the landing event on the moon.
Aliens:
public class Aliens implements LandingObserver {
@Override
public void observeLanding(String name) {
if(name.contains("Apollo")) {
System.out.println("They're distracted, lets invade earth!");
}
}
}
Nasa:
public class Nasa implements LandingObserver {
@Override
public void observeLanding(String name) {
if(name.contains("Apollo")) {
System.out.println("We made it!");
}
}
}
The client code is usually, for example:
Moon moon = new Moon();
moon.startSpying(new Nasa());
moon.startSpying(new Aliens());
moon.land("An asteroid");
moon.land("Apollo 11");
Using lambdas, the Aliens and Nasa classes, shown earlier, are unnecessary. In this case, the client is something like:
Moon moon = new Moon();
moon.startSpying(name -> {
if(name.contains("Apollo"))
System.out.println("We made it!");
});
moon.startSpying(name -> {
if(name.contains("Apollo"))
System.out.println("They're distracted, lets invade earth!");
});
moon.land("An asteroid");
moon.land("Apollo 11");