SlideShare ist ein Scribd-Unternehmen logo
Miroslav Wengner
Mastering Java enhancements like Profi
design patterns and anti-patterns?
Safe Harbour Statement
All what you will hear can be di
ff
erent, this presentation is for
motivational purposes …
Miroslav Wengner
• Husband, Father, Software Engineer, Author, Blogger, Technology Enthusiast
• Book Author: Practical Design Patterns for Java Developers [Packt]
• JCP: Executive Committee Board Member, OpenJDK Committer
• Java Mission Control Project, Open-Source projects
• Co-Author of Robo4J Project (Duke Award)
• Java Champion, JavaOne RockStar
• Principal Engineer at OpenValue
• Group Of Talented and Motivated Individuals
• Netherlands, Germany, Switzerland, Austria…
• Fun, Development, Trainings, Migration and
more…
Mechanical Engineer
Anitkythera mechanism
Agenda
• Rocking Java Platform and Enhancements
• OOP => EIPA
• SOLID thinking before we jump
• Do we like Anti-patterns ?
• [anti-patterns] natural appearance and technical depts
• [desing-patterns] creational, structural, behavioral
• [desing-patterns] concurrency
• Conclusion
• Q/A
Helicopter, … hieroglyphs, mystery ?
Java Platform and OpenJDK
Wake up <REPLACE_WITH_PROPER_NAME>
The Matrix has you …
Java Platform and OpenJDK
• Compiler => byte-code
• Dynamic Translation: JIT => instructions
• JVM Interpreter => EXPECTED RESULT
• Byte code optimisation: inlining, elimination, scalarization
static factory_method.Car produce(java.lang.String);
descriptor: (Ljava/lang/String;)Lfactory_method/Car;
fl
ags: (0x0008) ACC_STATIC
Code:
stack=7, locals=5, args_size=1
0: new #7 // class factory_method/FactoryMethodEvent
3: dup
…
19: aload_3
20: invokevirtual #17 // Method java/lang/String.hashCode:()I
23: lookupswitch { // 2
3135580: 48
3556498: 63
[java-platfom, enhacements]
• Important projects: Coin (7), Lamba(8), Jigsaw(9)…
• Project Valhalla: performance gains through generic API, primitives and value types, ML and BigData apps
• Hidden Classes(JEP-371), Warnings for Value-Based Classes (JEP-390)…
• Project Panama: interconnecting JVM and well de
fi
ned non-java APIs, easier access for I/O apps
• Foreign Function & Memory API (JEP-424), Vector API (JEP-426)…
• Project Amber: improving productivity through Java language evolution
• Local-Variable Type inference (JEP-286), Switch Extension (JEP-361), TextBlocks (JEP-378),
• Records (JEP-395), Pattern Matching (JEP-394, JEP-406, JEP-427), Sealed Classes (JEP-409), UTF-8 by Default (JEP-400),
• Record Patterns (JEP-405) …
• Project Loom: easy to use, hight-throughput, lightweight concurrency and programming approaches
• Virtual Threads (JEP-425), Structured Concurrency(JEP-428)…
?
OOP => EIPA
• Do NOT Repeat Yourself
• commonly APIE principles:
• Encapsulation: expose only required
• Inheritance: inevitable evolution
• Polymorphism: behaviour on demand
• Abstraction: standard features
Which one is the right ?
?
?
SOLID thinking before jump
• Single responsibility : engine (APIE)
• Open-Close: vehicle evolution (APIE)
• Liskov Substitution: car wash (AI)
• Interface Segregation: don’t force features (A,I)
• Dependency Inversion : di
ff
erent models in garage (A,I)
• Do NOT Repeat Yourself
• Separation of Concerns => Domains
• Extendability, Maintainability or Security
?
Do we like Anti-Patterns ?
• IMHO: yes we do
• it works for now … for me, FITYMI, Work On My Local Machine
• expectations too complex, keep it simple?
• Short cuts
• rotted code
• we
fi
x it later
• innovation through bottlenecks
• so when ? ?
[anti-pattern] natural appearance
• opposite for the good practice?
• highly risky, ine
ff
ective and counterproductive steps
• limits an ability to e
ff
ectively address the issue: bottleneck
• Java Platform is NOT a MAGIC :)
• squeezing the capabilities : EXAMPLE
• selecting the right tool: EXAMPLE
?
searching unicorns
Let’s dive deeper
[anti-patterns, platform] squeezing capabilities
?
MODEL:
record Sensor(int value) {}
LOGIC:
Collection<Sensor> set = provider.values();
for (Sensor e : set) {
SensorAlarmSystemUtil.evaluateAlarm(provider, e.value(), measurementCount);
}
UTILS:
void evaluateAlarm(Map<Integer, Sensor> storage, Integer criticalValue, long measurementNumber) {
if (!storage.containsKey(criticalValue)) {
System.out.println(“SHOULD NOT HAPPEN!”);
}
HOW DOES IT LOOK ?
[anti-patterns, platform] squeezing capabilities
• What about AutoBoxing ?
• code composition
• Platform optimalisation
• internal caches: Integers, Long …
?
@IntrinsicCandidate
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
WHAT ABOUT PAUSES ?
[anti-patterns, platform] squeezing capabilities
?
record Sensor(Integer value) {}
Collection<Sensor> set = provider.values();
for (Sensor e : set) {
SensorAlarmSystemUtil.evaluateAlarm(provider, e.value(), measurementCount);
}
void evaluateAlarm(Map<Integer, Sensor> storage, Integer criticalValue, long measurementNumber) {
if (!storage.containsKey(criticalValue)) {
System.out.println(“SHOULD NOT HAPPEN!”);
}
FEEL DIFFERENCE ?
[anti-patterns, apis] selecting the right tool
?
MODEL:
for (int i = 0; i < THREADS_NUMBER; i++) {
builder.addRunnable(
new VehicleAnalyticalWorker(i, ELEMENTS_NUMBER, new ArrayList<>(), new ArrayList<>())
);
}
LOGIC:
public int countIntersections(VehicleDataContainer c) {
int count = 0;
for (int n : collection) {
if (c.getCollection().contains(n)) {
count++;
}
}
return count;
}
HOW DOES IT LOOK ?
[anti-patterns, apis] selecting the right tool
• Internal JDK APIs, java.base?
• Are we familiar with them ?
• Impact:
• produce less code,
• e
ff
ective behaviour
• optimisation under the hood
• selecting the right tool
?
examples: LANG, MATH, NET, NIO, SECURITY, TIME,
UTIL -> Collection Framework … WHAT A HEAT?
[anti-patterns, apis] selecting the right tool
?
MODEL:
for (int i = 0; i < THREADS_NUMBER; i++) {
builder.addRunnable(
new VehicleAnalyticalWorker(i, ELEMENTS_NUMBER, new HashSet<>(), new HashSet<>())
);
}
FEEL DIFFERENCE ?
Anti-pattern known as a CODE SMELL
without understanding => another ANTI-PATTERN
[anti-patterns]: source-code
Cut and paste programming
Spaghetti code
Blob
Lava
fl
ow
Functional decomposition
Boat anchor
expecting next challenge from outdated
God Class
PoC to Production
past is knocking
keep it single
[anti-patterns]: architecture
?
Golden hammer
Continuous obsolescence
Input kludge
Working in mine
fi
eld
Ambiguous viewpoint
Poltergeists
Dead end
believe and not verify
interface Vehicle {
void checkEngine();
void initSystem();
void initRadio(); /*DON’T*/
void initCassettePlayer(); /*DON’T*/
void initMediaSystem(); /*CURRENT*/
}
Test?patch appears like magic …
don’t remove
old good approach
onion
don't touch
[desing-patterns]: creational, structural, behavioral and refactoring
• readable, maintainable code, performance is not the “target”
• CleanCode, Best Practices ~ Design Patterns ?
• Pareto Principle (80/20) : depends on perspective
• Start small to bild something useful!
?
Creational
Structural
Behavioral
Concurrency
[design-patterns] creational
?
Factory Method
Abstract Factory
Builder
Prototype
Singleton Object pool
Lazy initialization
Dependency
injection
[design-patterns] creational
?
Factory Method
public final class DefaultVehicleFactory implements VehicleFactory<VehicleType> {
public static int WEIGHT_SECURITY_EQUIPMENTS = 5;
@Override
public Vehicle produce(VehicleType type) {
return switch (type){
case STANDARD -> {
var v = new StandardVehicle(10);
v.addLoad(WEIGHT_SECURITY_EQUIPMENTS);
yield v;
}
case SPORT -> new SportVehicle("super-fast");
};
}
}
centralise the class instantiation
[design-patterns] creational
?
Builder
public record StartCommand(Vehicle vehicle, AtomicBoolean executed) implements VehicleCommand {
public static final class Builder {
private Vehicle builderVehicle;
public Builder addVehicle(Vehicle v){
this.builderVehicle = v;
return this;
}
public StartCommand build(){
return new StartCommand(this);
}
}
private StartCommand(Builder builder){
this(builder.builderVehicle, new AtomicBoolean());
}
….
separate the composition from the representation
Do not do it!
[design-patterns] structural
?
Adapter Bridge
Composite Decorator
Facade Filter
Flyweight Front controller
Marker Module
Proxy Twin
[design-patterns] structural
?
Adapter
sealed interface VehicleCommand permits StartCommand, StopCommand {..}
record StartCommand(…) implements VehicleCommand {
…
@Override
public void process(String command) {
if(command.contains("start")){
switch (vehicle){
case StandardVehicle v when v.getLoadWeight() > 1 ->
System.out.printf("""
%s with description:'%s', weight:'%d'%n""", v, v.getDescription(), v.getLoadWeight());
case StandardVehicle v -> System.out.printf("""
%s with description:'%s'%n""", v, v.getDescription());
case SportVehicle v -> System.out.println(v);
default -> System.out.println("NOTHING");
}
executed.set(true);
allows to work classes together
[design-patterns] structural
?
Facade
sealed interface VehicleCommand permits StartCommand, StopCommand {..}
uni
fi
ed interfaces to underlaying subsystems
public interface VehicleFactory<T> {
Vehicle produce(T type);
}
[design-patterns] behavioral
?
Caching Chain of responsibility
Command Interpreter Iterator
Mediator
Null Object
Observer
Pipeline
State
Strategy
Template
Visitor
[design-patterns] behavioral
?
Command like action, event on what client act
public record StartCommand(…) implements VehicleCommand {…
public final class StopCommand implements VehicleCommand {
private final Vehicle vehicle;
private boolean executed;
public StopCommand(Vehicle vehicle){
this.vehicle = vehicle;
}
@Override
public void process(String command) {
if(command.contains("stop")){
vehicle.stop();
executed = true;
…
[design-patterns] behavioral
?
Caching
Observer
public class Driver {
private final List<VehicleCommand> commands = new ArrayList<>();
public Driver addCommand(VehicleCommand command){…}
public void executeCommands(final String command){
commands.forEach(c -> {
// Records decomposition
if(c instanceof StartCommand(Vehicle v, AtomicBoolean state)){
….
}
public void printCommands() {
System.out.printf("""
Considered COMMANDS:%n%s""", commands.stream()
.map(VehicleCommand::status)
.collect(Collectors.joining("")));
react on demand reuse knowledge
[design-patterns] concurrency
?
Active Object Asynchronous Method
Balking Double Checked Locking
Read Write Lock Producer consumer
Scheduler Thread Pool
CONCURRENCY IS HARD <3
[design-patterns] concurrency
?
Balking
var vehicle = new Vehicle();
var numberOfDrivers = 5;
var executors = Executors.newFixedThreadPool(2);
for (int i = 0; i < numberOfDrivers; i++) {
executors.submit(vehicle::drive);
}
vehicle is changing states, solution to critical section
enum VehicleState {
MOVING,
STOPPED,
}
[design-patterns] concurrency
?
ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
var sensor = new Sensor(readWriteLock.readLock(), readWriteLock.writeLock());
var sensorWriter = new SensorWriter("writer-1", sensor);
var writerThread = getWriterThread(sensorWriter);
ExecutorService executor = Executors.newFixedThreadPool(NUMBER_READERS);
var readers = IntStream.range(0, NUMBER_READERS)
.boxed().map(i -> new SensorReader("reader-" + i, sensor, CYCLES_READER)).toList();
readers.forEach(executor::submit);
Read Write Lock natural exclusivity for lock acquisition
Conclusion
• Design Patterns and new JDK features helps to:
• improve code clarity: Sealed Classes, Pattern Matching
• reduce verbosity: Switch Statement improvements, Records
• enforce maintainability: Project Amber, Project Loom
• simpli
fi
ed composition: VirtualThreads, StructuredConcurrency, Switch, Local-Variable Type
• observability, pro
fi
ling, debugging and understanding
• Java as the 1st language for the JVM
?
Q / A
twitter: @miragemiko
github:@mirage22
email: miro@openvalue.de
Thank YOU !
References:
• Project Amber: https://openjdk.org/projects/amber/
• Project Valhalla: https://openjdk.org/projects/valhalla/
• Project Panama: https://openjdk.org/projects/panama/
• JFR Project: https://github.com/openjdk/jmc
• OpenJDK: https://openjdk.org/
• foojay.io: https://foojay.io/today/author/miro-wengner/
• OpenValue Blog: https://openvalue.blog/
• GitHub Examples: https://github.com/mirage22/mastering_java_enhancements
Title : Practical Design Patterns for Java Developers [PACKT]
Amazon: https://a.co/d/eizSkr2
GitHub: https://github.com/PacktPublishing/Practical-Design-Patterns-for-Java-Developers

Weitere ähnliche Inhalte

Ähnlich wie [meetup] Mastering Java enhancements like a Pro: practical design patterns and anti-patterns

WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 
Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...
Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...
Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...
seleniumconf
 

Ähnlich wie [meetup] Mastering Java enhancements like a Pro: practical design patterns and anti-patterns (20)

Eclipse e4 - Google Eclipse Day
Eclipse e4 - Google Eclipse DayEclipse e4 - Google Eclipse Day
Eclipse e4 - Google Eclipse Day
 
Ahead-Of-Time Compilation of Java Applications
Ahead-Of-Time Compilation of Java ApplicationsAhead-Of-Time Compilation of Java Applications
Ahead-Of-Time Compilation of Java Applications
 
The State of Managed Runtimes 2013, by Attila Szegedi
The State of Managed Runtimes 2013, by Attila SzegediThe State of Managed Runtimes 2013, by Attila Szegedi
The State of Managed Runtimes 2013, by Attila Szegedi
 
InvokeDynamic for Mere Mortals [JavaOne 2015 CON7682]
InvokeDynamic for Mere Mortals [JavaOne 2015 CON7682]InvokeDynamic for Mere Mortals [JavaOne 2015 CON7682]
InvokeDynamic for Mere Mortals [JavaOne 2015 CON7682]
 
Eclipse Testing Day 2010. Xored Q7
Eclipse Testing Day 2010. Xored Q7Eclipse Testing Day 2010. Xored Q7
Eclipse Testing Day 2010. Xored Q7
 
Java For beginners and CSIT and IT students
Java  For beginners and CSIT and IT studentsJava  For beginners and CSIT and IT students
Java For beginners and CSIT and IT students
 
Autonomous Machines with Project Bonsai
Autonomous Machines with Project BonsaiAutonomous Machines with Project Bonsai
Autonomous Machines with Project Bonsai
 
Java1 in mumbai
Java1 in mumbaiJava1 in mumbai
Java1 in mumbai
 
Eclipse UI automation
Eclipse UI automationEclipse UI automation
Eclipse UI automation
 
UML for Aspect Oriented Design
UML for Aspect Oriented DesignUML for Aspect Oriented Design
UML for Aspect Oriented Design
 
Eclipse 40 and Eclipse e4
Eclipse 40 and Eclipse e4 Eclipse 40 and Eclipse e4
Eclipse 40 and Eclipse e4
 
Protractor survival guide
Protractor survival guideProtractor survival guide
Protractor survival guide
 
JS Essence
JS EssenceJS Essence
JS Essence
 
Java Programming concept
Java Programming concept Java Programming concept
Java Programming concept
 
Letest
LetestLetest
Letest
 
Microservices Chaos Testing at Jet
Microservices Chaos Testing at JetMicroservices Chaos Testing at Jet
Microservices Chaos Testing at Jet
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Programming in java basics
Programming in java  basicsProgramming in java  basics
Programming in java basics
 
Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...
Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...
Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...
 
6 Traits of a Successful Test Automation Architecture
6 Traits of a Successful Test Automation Architecture6 Traits of a Successful Test Automation Architecture
6 Traits of a Successful Test Automation Architecture
 

Mehr von Miro Wengner

Mehr von Miro Wengner (9)

ASML_FlightRecorderMeetsJava.pdf
ASML_FlightRecorderMeetsJava.pdfASML_FlightRecorderMeetsJava.pdf
ASML_FlightRecorderMeetsJava.pdf
 
DevDays: Profiling With Java Flight Recorder
DevDays: Profiling With Java Flight RecorderDevDays: Profiling With Java Flight Recorder
DevDays: Profiling With Java Flight Recorder
 
JMC/JFR: Kotlin spezial
JMC/JFR: Kotlin spezialJMC/JFR: Kotlin spezial
JMC/JFR: Kotlin spezial
 
Plug Hardware and Play Java
Plug Hardware and Play JavaPlug Hardware and Play Java
Plug Hardware and Play Java
 
From Concept to Robotic Overlord with Robo4J
From Concept to Robotic Overlord with Robo4J From Concept to Robotic Overlord with Robo4J
From Concept to Robotic Overlord with Robo4J
 
JavaOne 2016 :: Bringing Robot online with Robo4j Framework
JavaOne 2016 :: Bringing Robot online with Robo4j FrameworkJavaOne 2016 :: Bringing Robot online with Robo4j Framework
JavaOne 2016 :: Bringing Robot online with Robo4j Framework
 
JavaOne presentation - building steps :: Number42 is alive
JavaOne presentation - building steps :: Number42 is alive JavaOne presentation - building steps :: Number42 is alive
JavaOne presentation - building steps :: Number42 is alive
 
The Robot under dictate of the LegoMindStorm Java Concurrency API
The Robot under dictate of the LegoMindStorm Java Concurrency APIThe Robot under dictate of the LegoMindStorm Java Concurrency API
The Robot under dictate of the LegoMindStorm Java Concurrency API
 
How RaspberryPi workers building GraphDatabase
How RaspberryPi workers building GraphDatabaseHow RaspberryPi workers building GraphDatabase
How RaspberryPi workers building GraphDatabase
 

Kürzlich hochgeladen

Kürzlich hochgeladen (20)

FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
Demystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John StaveleyDemystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John Staveley
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
 

[meetup] Mastering Java enhancements like a Pro: practical design patterns and anti-patterns

  • 1. Miroslav Wengner Mastering Java enhancements like Profi design patterns and anti-patterns?
  • 2. Safe Harbour Statement All what you will hear can be di ff erent, this presentation is for motivational purposes …
  • 3. Miroslav Wengner • Husband, Father, Software Engineer, Author, Blogger, Technology Enthusiast • Book Author: Practical Design Patterns for Java Developers [Packt] • JCP: Executive Committee Board Member, OpenJDK Committer • Java Mission Control Project, Open-Source projects • Co-Author of Robo4J Project (Duke Award) • Java Champion, JavaOne RockStar • Principal Engineer at OpenValue
  • 4. • Group Of Talented and Motivated Individuals • Netherlands, Germany, Switzerland, Austria… • Fun, Development, Trainings, Migration and more…
  • 6. Agenda • Rocking Java Platform and Enhancements • OOP => EIPA • SOLID thinking before we jump • Do we like Anti-patterns ? • [anti-patterns] natural appearance and technical depts • [desing-patterns] creational, structural, behavioral • [desing-patterns] concurrency • Conclusion • Q/A
  • 8. Java Platform and OpenJDK Wake up <REPLACE_WITH_PROPER_NAME> The Matrix has you …
  • 9. Java Platform and OpenJDK • Compiler => byte-code • Dynamic Translation: JIT => instructions • JVM Interpreter => EXPECTED RESULT • Byte code optimisation: inlining, elimination, scalarization static factory_method.Car produce(java.lang.String); descriptor: (Ljava/lang/String;)Lfactory_method/Car; fl ags: (0x0008) ACC_STATIC Code: stack=7, locals=5, args_size=1 0: new #7 // class factory_method/FactoryMethodEvent 3: dup … 19: aload_3 20: invokevirtual #17 // Method java/lang/String.hashCode:()I 23: lookupswitch { // 2 3135580: 48 3556498: 63
  • 10. [java-platfom, enhacements] • Important projects: Coin (7), Lamba(8), Jigsaw(9)… • Project Valhalla: performance gains through generic API, primitives and value types, ML and BigData apps • Hidden Classes(JEP-371), Warnings for Value-Based Classes (JEP-390)… • Project Panama: interconnecting JVM and well de fi ned non-java APIs, easier access for I/O apps • Foreign Function & Memory API (JEP-424), Vector API (JEP-426)… • Project Amber: improving productivity through Java language evolution • Local-Variable Type inference (JEP-286), Switch Extension (JEP-361), TextBlocks (JEP-378), • Records (JEP-395), Pattern Matching (JEP-394, JEP-406, JEP-427), Sealed Classes (JEP-409), UTF-8 by Default (JEP-400), • Record Patterns (JEP-405) … • Project Loom: easy to use, hight-throughput, lightweight concurrency and programming approaches • Virtual Threads (JEP-425), Structured Concurrency(JEP-428)… ?
  • 11. OOP => EIPA • Do NOT Repeat Yourself • commonly APIE principles: • Encapsulation: expose only required • Inheritance: inevitable evolution • Polymorphism: behaviour on demand • Abstraction: standard features Which one is the right ? ? ?
  • 12. SOLID thinking before jump • Single responsibility : engine (APIE) • Open-Close: vehicle evolution (APIE) • Liskov Substitution: car wash (AI) • Interface Segregation: don’t force features (A,I) • Dependency Inversion : di ff erent models in garage (A,I) • Do NOT Repeat Yourself • Separation of Concerns => Domains • Extendability, Maintainability or Security ?
  • 13. Do we like Anti-Patterns ? • IMHO: yes we do • it works for now … for me, FITYMI, Work On My Local Machine • expectations too complex, keep it simple? • Short cuts • rotted code • we fi x it later • innovation through bottlenecks • so when ? ?
  • 14. [anti-pattern] natural appearance • opposite for the good practice? • highly risky, ine ff ective and counterproductive steps • limits an ability to e ff ectively address the issue: bottleneck • Java Platform is NOT a MAGIC :) • squeezing the capabilities : EXAMPLE • selecting the right tool: EXAMPLE ? searching unicorns Let’s dive deeper
  • 15. [anti-patterns, platform] squeezing capabilities ? MODEL: record Sensor(int value) {} LOGIC: Collection<Sensor> set = provider.values(); for (Sensor e : set) { SensorAlarmSystemUtil.evaluateAlarm(provider, e.value(), measurementCount); } UTILS: void evaluateAlarm(Map<Integer, Sensor> storage, Integer criticalValue, long measurementNumber) { if (!storage.containsKey(criticalValue)) { System.out.println(“SHOULD NOT HAPPEN!”); } HOW DOES IT LOOK ?
  • 16. [anti-patterns, platform] squeezing capabilities • What about AutoBoxing ? • code composition • Platform optimalisation • internal caches: Integers, Long … ? @IntrinsicCandidate public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } WHAT ABOUT PAUSES ?
  • 17. [anti-patterns, platform] squeezing capabilities ? record Sensor(Integer value) {} Collection<Sensor> set = provider.values(); for (Sensor e : set) { SensorAlarmSystemUtil.evaluateAlarm(provider, e.value(), measurementCount); } void evaluateAlarm(Map<Integer, Sensor> storage, Integer criticalValue, long measurementNumber) { if (!storage.containsKey(criticalValue)) { System.out.println(“SHOULD NOT HAPPEN!”); } FEEL DIFFERENCE ?
  • 18. [anti-patterns, apis] selecting the right tool ? MODEL: for (int i = 0; i < THREADS_NUMBER; i++) { builder.addRunnable( new VehicleAnalyticalWorker(i, ELEMENTS_NUMBER, new ArrayList<>(), new ArrayList<>()) ); } LOGIC: public int countIntersections(VehicleDataContainer c) { int count = 0; for (int n : collection) { if (c.getCollection().contains(n)) { count++; } } return count; } HOW DOES IT LOOK ?
  • 19. [anti-patterns, apis] selecting the right tool • Internal JDK APIs, java.base? • Are we familiar with them ? • Impact: • produce less code, • e ff ective behaviour • optimisation under the hood • selecting the right tool ? examples: LANG, MATH, NET, NIO, SECURITY, TIME, UTIL -> Collection Framework … WHAT A HEAT?
  • 20. [anti-patterns, apis] selecting the right tool ? MODEL: for (int i = 0; i < THREADS_NUMBER; i++) { builder.addRunnable( new VehicleAnalyticalWorker(i, ELEMENTS_NUMBER, new HashSet<>(), new HashSet<>()) ); } FEEL DIFFERENCE ? Anti-pattern known as a CODE SMELL without understanding => another ANTI-PATTERN
  • 21. [anti-patterns]: source-code Cut and paste programming Spaghetti code Blob Lava fl ow Functional decomposition Boat anchor expecting next challenge from outdated God Class PoC to Production past is knocking keep it single
  • 22. [anti-patterns]: architecture ? Golden hammer Continuous obsolescence Input kludge Working in mine fi eld Ambiguous viewpoint Poltergeists Dead end believe and not verify interface Vehicle { void checkEngine(); void initSystem(); void initRadio(); /*DON’T*/ void initCassettePlayer(); /*DON’T*/ void initMediaSystem(); /*CURRENT*/ } Test?patch appears like magic … don’t remove old good approach onion don't touch
  • 23. [desing-patterns]: creational, structural, behavioral and refactoring • readable, maintainable code, performance is not the “target” • CleanCode, Best Practices ~ Design Patterns ? • Pareto Principle (80/20) : depends on perspective • Start small to bild something useful! ? Creational Structural Behavioral Concurrency
  • 24. [design-patterns] creational ? Factory Method Abstract Factory Builder Prototype Singleton Object pool Lazy initialization Dependency injection
  • 25. [design-patterns] creational ? Factory Method public final class DefaultVehicleFactory implements VehicleFactory<VehicleType> { public static int WEIGHT_SECURITY_EQUIPMENTS = 5; @Override public Vehicle produce(VehicleType type) { return switch (type){ case STANDARD -> { var v = new StandardVehicle(10); v.addLoad(WEIGHT_SECURITY_EQUIPMENTS); yield v; } case SPORT -> new SportVehicle("super-fast"); }; } } centralise the class instantiation
  • 26. [design-patterns] creational ? Builder public record StartCommand(Vehicle vehicle, AtomicBoolean executed) implements VehicleCommand { public static final class Builder { private Vehicle builderVehicle; public Builder addVehicle(Vehicle v){ this.builderVehicle = v; return this; } public StartCommand build(){ return new StartCommand(this); } } private StartCommand(Builder builder){ this(builder.builderVehicle, new AtomicBoolean()); } …. separate the composition from the representation Do not do it!
  • 27. [design-patterns] structural ? Adapter Bridge Composite Decorator Facade Filter Flyweight Front controller Marker Module Proxy Twin
  • 28. [design-patterns] structural ? Adapter sealed interface VehicleCommand permits StartCommand, StopCommand {..} record StartCommand(…) implements VehicleCommand { … @Override public void process(String command) { if(command.contains("start")){ switch (vehicle){ case StandardVehicle v when v.getLoadWeight() > 1 -> System.out.printf(""" %s with description:'%s', weight:'%d'%n""", v, v.getDescription(), v.getLoadWeight()); case StandardVehicle v -> System.out.printf(""" %s with description:'%s'%n""", v, v.getDescription()); case SportVehicle v -> System.out.println(v); default -> System.out.println("NOTHING"); } executed.set(true); allows to work classes together
  • 29. [design-patterns] structural ? Facade sealed interface VehicleCommand permits StartCommand, StopCommand {..} uni fi ed interfaces to underlaying subsystems public interface VehicleFactory<T> { Vehicle produce(T type); }
  • 30. [design-patterns] behavioral ? Caching Chain of responsibility Command Interpreter Iterator Mediator Null Object Observer Pipeline State Strategy Template Visitor
  • 31. [design-patterns] behavioral ? Command like action, event on what client act public record StartCommand(…) implements VehicleCommand {… public final class StopCommand implements VehicleCommand { private final Vehicle vehicle; private boolean executed; public StopCommand(Vehicle vehicle){ this.vehicle = vehicle; } @Override public void process(String command) { if(command.contains("stop")){ vehicle.stop(); executed = true; …
  • 32. [design-patterns] behavioral ? Caching Observer public class Driver { private final List<VehicleCommand> commands = new ArrayList<>(); public Driver addCommand(VehicleCommand command){…} public void executeCommands(final String command){ commands.forEach(c -> { // Records decomposition if(c instanceof StartCommand(Vehicle v, AtomicBoolean state)){ …. } public void printCommands() { System.out.printf(""" Considered COMMANDS:%n%s""", commands.stream() .map(VehicleCommand::status) .collect(Collectors.joining(""))); react on demand reuse knowledge
  • 33. [design-patterns] concurrency ? Active Object Asynchronous Method Balking Double Checked Locking Read Write Lock Producer consumer Scheduler Thread Pool CONCURRENCY IS HARD <3
  • 34. [design-patterns] concurrency ? Balking var vehicle = new Vehicle(); var numberOfDrivers = 5; var executors = Executors.newFixedThreadPool(2); for (int i = 0; i < numberOfDrivers; i++) { executors.submit(vehicle::drive); } vehicle is changing states, solution to critical section enum VehicleState { MOVING, STOPPED, }
  • 35. [design-patterns] concurrency ? ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); var sensor = new Sensor(readWriteLock.readLock(), readWriteLock.writeLock()); var sensorWriter = new SensorWriter("writer-1", sensor); var writerThread = getWriterThread(sensorWriter); ExecutorService executor = Executors.newFixedThreadPool(NUMBER_READERS); var readers = IntStream.range(0, NUMBER_READERS) .boxed().map(i -> new SensorReader("reader-" + i, sensor, CYCLES_READER)).toList(); readers.forEach(executor::submit); Read Write Lock natural exclusivity for lock acquisition
  • 36. Conclusion • Design Patterns and new JDK features helps to: • improve code clarity: Sealed Classes, Pattern Matching • reduce verbosity: Switch Statement improvements, Records • enforce maintainability: Project Amber, Project Loom • simpli fi ed composition: VirtualThreads, StructuredConcurrency, Switch, Local-Variable Type • observability, pro fi ling, debugging and understanding • Java as the 1st language for the JVM ?
  • 37. Q / A twitter: @miragemiko github:@mirage22 email: miro@openvalue.de Thank YOU !
  • 38. References: • Project Amber: https://openjdk.org/projects/amber/ • Project Valhalla: https://openjdk.org/projects/valhalla/ • Project Panama: https://openjdk.org/projects/panama/ • JFR Project: https://github.com/openjdk/jmc • OpenJDK: https://openjdk.org/ • foojay.io: https://foojay.io/today/author/miro-wengner/ • OpenValue Blog: https://openvalue.blog/ • GitHub Examples: https://github.com/mirage22/mastering_java_enhancements Title : Practical Design Patterns for Java Developers [PACKT] Amazon: https://a.co/d/eizSkr2 GitHub: https://github.com/PacktPublishing/Practical-Design-Patterns-for-Java-Developers