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
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!
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);
}
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
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 !