This article contains the source code of examples used in 'Design Patterns in the Light of Lambda Expressions by Venkat Subramaniam'. Example demonstrates the Light-weight Strategy design pattern, Delegate design pattern Decoration design pattern and Fluent API using lambda expressions.
Video
Source Code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.awt.Color; | |
import java.util.List; | |
import java.util.Objects; | |
import java.util.function.Consumer; | |
import java.util.function.Function; | |
import java.util.function.Predicate; | |
import java.util.function.Supplier; | |
import java.util.stream.IntStream; | |
import java.util.stream.Stream; | |
@SuppressWarnings("unused") | |
class LambdaDesign { | |
public static void main(String[] args) { | |
replaceAnonymous(); | |
System.out.println("------------------------------------------------------------------------"); | |
new LightweightStrategy().demo(); | |
System.out.println("------------------------------------------------------------------------"); | |
new DelegateUsingLambda().demo(); | |
System.out.println("------------------------------------------------------------------------"); | |
new Decoration().demo(); | |
System.out.println("------------------------------------------------------------------------"); | |
new Decoration().demo1(); | |
System.out.println("------------------------------------------------------------------------"); | |
new Fluent().demo(); | |
} | |
static void replaceAnonymous() { | |
/*Thread thread = new Thread(new Runnable() { | |
@Override | |
public void run() { | |
System.out.println("In thread"); | |
} | |
});*/ | |
Thread thread = new Thread(() -> System.out.println("in thread...")); | |
thread.start(); | |
System.out.println("In main thread..."); | |
} | |
} | |
@SuppressWarnings("unused") | |
class LightweightStrategy { | |
void demo() { | |
List<Integer> nums = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); | |
/*System.out.println("Calculation.sum(nums) = " + Calculation.sum(nums)); | |
System.out.println("Calculation.sumOfEvens(nums) = " + Calculation.sumOfEvens(nums)); | |
System.out.println("Calculation.sumOfOdds(nums) = " + Calculation.sumOfOdds(nums)); | |
*/ | |
System.out.println("Calculation.sum(nums) = " + sum(nums, n -> true)); | |
System.out.println("Calculation.sumOfEvens(nums) = " + sum(nums, n -> n % 2 == 0)); | |
System.out.println("Calculation.sumOfOdds(nums) = " + sum(nums, n -> n % 2 != 0)); | |
} | |
int sum(List<Integer> list) { | |
return list.stream() | |
.reduce(0, Integer::sum); | |
} | |
int sumOfEvens(List<Integer> list) { | |
return list.stream() | |
.filter(n -> n % 2 == 0 ) | |
.reduce(0, Integer::sum); | |
} | |
int sumOfOdds(List<Integer> list) { | |
return list.stream() | |
.filter(n -> n % 2 != 0 ) | |
.reduce(0, Integer::sum); | |
} | |
int sum(List<Integer> list, Predicate<Integer> pred) { | |
return list.stream() | |
.filter(pred) | |
//.reduce(0, (n1, n2) -> n1 + n2); | |
.reduce(0, Integer::sum); | |
// OR | |
/*return list.stream() | |
.filter(n -> pred.test(n)) | |
.mapToInt(e -> e) | |
.sum(); | |
*/ | |
} | |
} | |
@SuppressWarnings("unused") | |
// Lazy calling | |
class DelegateUsingLambda { | |
class Lazy<T> { | |
private T instance; | |
private Supplier<T> supplier; | |
public Lazy(Supplier<T> t) { | |
supplier = t; | |
} | |
T get() { | |
if (instance == null) { | |
instance = supplier.get(); | |
supplier = null; | |
} | |
return instance; | |
} | |
} | |
void demo() { | |
int n = 5; | |
var sum = new Lazy<>(() -> sumOfNumbers(n)); | |
if ( n > 5 && sum.get() > 8) { | |
System.out.println("true: perform some logic : " + sum.get()); | |
} else { | |
System.out.println("false: perform some logic"); | |
} | |
} | |
// Heavy Operation | |
int sumOfNumbers(int n) { | |
System.out.println("sumOfNumbers is called with n = " + n); | |
return IntStream.range(1, n).sum(); | |
} | |
} | |
@SuppressWarnings("unused") | |
class Decoration { | |
void demo1() { | |
Function<Integer, Integer> doubled = n -> n * 2; | |
perform(5, "doubled", doubled); | |
perform(10, "double and increment", doubled.andThen(n -> n + 1)); | |
} | |
void perform(int n, String msg, Function<Integer, Integer> function) { | |
System.out.println("n = [" + n + "], msg = [" + msg + "], function = [" + function.apply(n) + "]"); | |
} | |
@SuppressWarnings("unchecked") | |
void demo() { | |
Camera cam = new Camera(Color::brighter, Color::darker); | |
System.out.println("cam.click(new Color(125, 125, 125)) = " | |
+ cam.click(new Color(125, 125, 125))); | |
} | |
class Camera { | |
Function<Color, Color> filter; | |
public Camera(Function<Color, Color> ... filters) { | |
filter = Stream.of(filters) | |
.reduce(Function.identity(), Function::andThen); | |
} | |
Color click(Color input) { | |
return filter.apply(input); | |
} | |
} | |
} | |
class Fluent { | |
void demo() { | |
Mailer.send ( mailer -> mailer.from("from@domain.com") | |
.to("to@domain.com") | |
.subject("Subject...") | |
.body("Hi.... Regards, XXX")); | |
} | |
} | |
class Mailer { | |
private static Mailer mailer; | |
private String from, subject, body, to; | |
private Mailer() {} | |
Mailer from(String s) { | |
mailer.from = s; | |
return mailer; | |
} | |
Mailer subject(String s) { | |
mailer.subject = s; | |
return mailer; | |
} | |
Mailer body(String s) { | |
mailer.body = s; | |
return mailer; | |
} | |
Mailer to(String s) { | |
mailer.to = s; | |
return mailer; | |
} | |
static void send(Consumer<Mailer> consumer) { | |
Objects.requireNonNull(consumer); | |
mailer = new Mailer(); | |
consumer.accept(mailer); | |
System.out.println("Sending with " + mailer); | |
} | |
@Override | |
public String toString() { | |
return "Mailer{" + | |
"from='" + from + '\'' + | |
", to='" + to + '\'' + | |
", subject='" + subject + '\'' + | |
", body='" + body + '\'' + | |
'}'; | |
} | |
} |
Emoticon Emoticon