SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK...
Transcript of SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK...
![Page 1: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/1.jpg)
SOLID mit Java 8
![Page 2: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/2.jpg)
Roland MastSybit GmbHAgiler Software-ArchitektScrum [email protected]
![Page 3: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/3.jpg)
Roland MastSybit GmbHAgiler [email protected]
![Page 4: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/4.jpg)
• Single responsibility
• Open Closed
• Liskov Substitution
• Interface Segregation
• Dependency Inversion
SOLID und Uncle Bob
![Page 5: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/5.jpg)
// Strings in einem Array nach deren Länge sortieren
Arrays.sort(strings, new Comparator<String>() {public int compare(String a, String b) {
return Integer.compare(a.length(), b.length());}
});
Arrays.sort(strings, (a, b) -> Integer.compare(a.length(), b.length()));
// Strings alphabetisch sortieren
Arrays.sort(strings, String::compareToIgnoreCase);
Lambdas
![Page 6: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/6.jpg)
Single ResponsibilityPrinciple?Single ResponsibilityPrinciple?
A class should have one, and only one, reason to change.
A class should have one, and only one, reason to change.
![Page 7: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/7.jpg)
List<Person> persons = Arrays.asList(// name, age, sizenew Person("Max", 18, 1.9),new Person("Peter", 23, 1.8),new Person("Pamela", 23, 1.6),new Person("David", 12, 1.5));
Double averageSize = persons.stream().filter(p -> p.age >= 18).collect(Collectors.averagingDouble(p -> p.size));
Lambdas in Streams
Iteration über die Daten
Filtern anstattif (age >= 18) {
keep();
}Collectors berechnet den Durchschnitt
Single Responsibility
![Page 8: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/8.jpg)
public interface BinaryOperation {long identity();long binaryOperator(long a, long b);
}
public class Sum implements BinaryOperation {@Overridepublic long identity() { return 0L; }
@Overridepublic long binaryOperator(long a, long b) {
return i1 + i2;}
}
Single Responsibility
private long[] data;public long solve() {
int threadCount = Runtime.getRuntime().availableProcessors();ForkJoinPool pool = new ForkJoinPool(threadCount);pool.invoke(this);return res;
}protected void compute() {
if (data.length == 1) {res=operation.binaryOperator(operation.identity(), data[0]);
} else {int midpoint = data.length / 2;long[] l1 = Arrays.copyOfRange(data, 0, midpoint);long[] l2 = Arrays.copyOfRange(data, midpoint, data.length);SolverJ7 s1 = new SolverJ7(l1, operation);SolverJ7 s2 = new SolverJ7(l2, operation);invokeAll(s1, s2);res = operation.binaryOperator(s1.res, s2.res);
}}
Daten müssen selbst aufgeteilt und zusammengeführt werden
Interface und Klasse definieren Operation
Parallele SummenberechnungThreadpool muss selbst erzeugt werden
![Page 9: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/9.jpg)
private long[] data;
public long sumUp() {return LongStream.of(data)
.parallel()
.reduce(0, (a, b) -> a + b);}
Parallel ReduceSingle Responsibility
![Page 10: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/10.jpg)
Single Responsibility Principle
Lambdas + Streams
Kapseln Verantwotlichkeiten
![Page 11: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/11.jpg)
Open/ClosedPrinciple?Open/ClosedPrinciple?
You should be able to extend a classes behavior, without modifying it.
You should be able to extend a classes behavior, without modifying it.
![Page 12: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/12.jpg)
public interface Iterable<T> {Iterator<T> iterator();
}
Iterable Interface
public interface Iterable<T> {Iterator<T> iterator();
void forEach(Consumer<? super T> action);Spliterator<T> spliterator();
}
Open/Closed
![Page 13: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/13.jpg)
public interface Iterable<T> {Iterator<T> iterator();
default void forEach(Consumer<? super T> action) {for (T t : this) { action.accept(t); }
}
default Spliterator<T> spliterator() {return Spliterators.spliteratorUnknownSize(iterator(), 0);
}}
Default-ImplementationOpen/Closed
![Page 14: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/14.jpg)
Open/Closed Principle
Default-Implementierungen in Interfaces
Flexibel Frameworks erweitern
![Page 15: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/15.jpg)
Liskov's Substitution Principle?Liskov's Substitution Principle?
Derived classes must be substitutable for their base classes.
Derived classes must be substitutable for their base classes.
“No new exceptions should be thrown by methods of the subtype, except where those exceptions are themselves subtypes of exceptions thrown by the methods of the supertype.”
![Page 16: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/16.jpg)
/*** Find the first occurrence of a text in files
* given by a list of file names.*/
public Optional<String> findFirst(String text, List<String> fileNames) {
return fileNames.stream().map(name -> Paths.get(name))
.flatMap(path -> Files.lines(path))
.filter(s -> s.contains(text))
.findFirst();}
Checked Exception in StreamsLiskov‘s Substitution
public final class Files {
public static Stream<String> lines(Path path)throws IOException {
BufferedReader br =Files.newBufferedReader(path);
try {return br.lines()
.onClose(asUncheckedRunnable(br));} catch (Error|RuntimeException e) {
….. 8< ……………………br.close();
….. 8< ……………………}
}
IOException
![Page 17: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/17.jpg)
/*** Find the first occurrence of a text in files
* given by a list of file names.*/
public Optional<String> findFirst(String text, List<String> fileNames) {
return fileNames.stream().map(name -> Paths.get(name))
.flatMap(path -> mylines(path))
.filter(s -> s.contains(text))
.findFirst();}
Handle IOExceptionLiskov‘s Substitution
private Stream<String> mylines(Path path){try (BufferedReader br =
Files.newBufferedReader(path)) {
return br.lines().onClose(asUncheckedRunnable(br));
} catch (IOException e) {throw new UncheckedIOException(e);
}}
![Page 18: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/18.jpg)
private static Runnable asUncheckedRunnable(Closeable c) {return () -> {
try {c.close();
} catch (IOException e) { throw new UncheckedIOException(e); }};
}
Close StreamLiskov‘s Substitution
![Page 19: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/19.jpg)
Liskov´s Substitution Principle
Files + BufferedReader
UncheckedIOException nur bei neuen Methoden
![Page 20: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/20.jpg)
Interface Segregation Principle?Interface Segregation Principle?
Make fine grained interfaces that are client specific.
Make fine grained interfaces that are client specific.
![Page 21: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/21.jpg)
public interface ParserContext {Reader getReader();void handleLine(String line);void handleException(Exception e);
}public void parse(final ParserContext context) {
try (BufferedReader br = new BufferedReader(context.getReader())) {String line;do {
line = br.readLine();if (line != null) { context.handleLine(line); }
} while (line != null)} catch (IOException e) { context.handleException(e); }
}
Functional InterfacesInterface Segregation
1 Interface mit3 Methoden
![Page 22: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/22.jpg)
<T> T withLinesOf(Supplier<Reader> reader,Function<Stream<String>, T> handleLines,Function<Exception, RuntimeException> onError) {
try (BufferedReader br = new BufferedReader(reader.get())) {return handleLines.apply(br.lines());
} catch (IOException e) {throw onError.apply(e);
}}
Functional InterfacesInterface Segregation
3 separate Interfaces
![Page 23: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/23.jpg)
LocalTimeInterface Segregation
![Page 24: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/24.jpg)
Interface Segregation Principle
Functional Interfaces
Ermutigen zum Auftrennen von Interfaces
![Page 25: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/25.jpg)
Dependency Inversion Principle?Dependency Inversion Principle?
Depend on abstractions, not on concretions.Depend on abstractions, not on concretions.
![Page 26: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/26.jpg)
Warning: JDK internal APIs are unsupported andprivate to JDK implementation that are
subject to be removed or changed incompatibly and could break your application.
Please modify your code to eliminate dependency on any JDK internal APIs.
For the most recent update on JDK internal API replacements, please check:
https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
jdeps -jdkinternalsDepedency Inversion
![Page 27: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/27.jpg)
jdeps -jdkinternals classes
classes -> C:\Program Files\Java\jdk1.8.0_74\jre\lib\rt.jar
de.sybit.warranty.facade.impl.DefaultWarrantyFacade (classes)
-> com.sun.xml.internal.fastinfoset.stax.events.UtilJDK internal API (rt.jar)
jdepsDepedency Inversion
return (Util.isEmptyString(param) || "*".equals(param));
![Page 28: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/28.jpg)
public List<String> filterError(Reader reader) {try (BufferedReader br = new BufferedReader(reader)){
return br.lines().filter(line -> line.contains("ERROR")).map(line -> line.split(":")[1]).collect(toList());
} catch (IOException e) {throw new LogAnalyseException(e);
}}
LambdasDepedency Inversion
Filterimplementierung ist abhängig von konkreten Implementierungen:
• BufferedReader
• IOException
![Page 29: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/29.jpg)
public class Parser {<T> T withLinesOf(Reader reader,
Function<Stream<String>, T> handleLines,Function<Exception, RuntimeException> onError) {
try (BufferedReader br = new BufferedReader(reader)) {return handleLines.apply(br.lines());
} catch (IOException e) {throw onError.apply(e);
}}
}
LambdasDepedency Inversion
withLinesOf() kapselt die Abhängigkeiten
![Page 30: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/30.jpg)
private Parser parser = new Parser();
public List<String> filterError(Reader reader) {return parser.withLinesOf(reader,
lines -> lines
.filter(line -> line.contains("ERROR"))
.map(line -> line.split(":")[1])
.collect(toList()),LogAnalyseException::new);
}
LambdasDepedency Inversion
filterError() ist nur noch abhängig von Abstraktionen
![Page 31: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/31.jpg)
Dependency Inversion Principle
Lambdas
Sind starke Abstraktionen
![Page 32: SOLID mit Java 8 · 2017-10-05 · Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break](https://reader035.fdocuments.us/reader035/viewer/2022063006/5fb58777c0fd2007af478c9b/html5/thumbnails/32.jpg)
“The principles of software design still apply, regardless of your programming style. The fact that you've decided to use a [functional] language that doesn't have an assignment operator does not mean that you can ignore the Single Responsibility Principle; or that the Open Closed Principle is somehow automatic.”
Robert C. Martin: OO vs FP (24 November 2014)http://blog.cleancoder.com/uncle-bob/2014/11/24/FPvsOO.html
SOLID mit Java 8