Java’s new paradigm | Ties van de Ven
Summary
TLDRThis talk delves into the concept of data-oriented programming, emphasizing its distinction from object-oriented and functional programming paradigms. The speaker explores the 'why' behind data-oriented programming, its impact on software architecture, and how it can enhance scalability. The discussion also highlights Java's new language features like records, sealed classes, and pattern matching, which support this programming style. The speaker advocates for a pragmatic approach, using the best tools for each situation rather than adhering strictly to one paradigm.
Takeaways
- 😀 The speaker is passionate about software engineering fundamentals and was intrigued by the concept of data-oriented programming in Java after reading an article by Brian Goetz.
- 🔍 The speaker embarked on a journey to understand data-oriented programming, finding it to be a different, rather than a superior, approach to software development compared to object-oriented and functional programming.
- 📚 Brian Goetz's talk on functional and object-oriented programming emphasizes the idea of not being dogmatic and being a better programmer by using the right tools for the situation.
- 🤔 The main question the speaker sought to answer in their talk is the definition and essence of data-oriented programming, as they couldn't find a clear answer online.
- 🛠️ Data-oriented programming focuses on the data itself rather than the types or classes that hold the data, which can lead to more scalable and performance-optimized applications.
- 🔄 The speaker discusses the concept of data streams and how most applications can be viewed as a series of data transformations involving map, filter, and branch operations.
- 🧱 The use of types in Java and their downsides, such as not naturally mapping to other types, is contrasted with the efficiency of using data structures like hashmaps that are designed for operations like map and filter.
- 📈 Data-oriented programming can offer performance benefits, especially in gaming and other real-time applications where frame rate is critical.
- 🏗️ The talk also covers how data-oriented programming affects software architecture, advocating for separating use cases from data to create a cleaner object graph and easier scalability.
- 🆕 The introduction of new Java language features like records, sealed classes, and pattern matching are discussed as tools that enable data-oriented programming, but not as the central focus.
- ⚠️ The speaker advises against being dogmatic about any programming paradigm, suggesting that the best approach often involves a combination of object-oriented, functional, and data-oriented programming.
Q & A
What is the main focus of the talk on data-oriented programming in Java?
-The talk focuses on explaining what data-oriented programming is, its mindset, and how it differs from object-oriented and functional programming. It also discusses the implications of data-oriented programming on software architecture and the benefits of new language features like records, sealed classes, and pattern matching in Java.
Why was the author initially excited about data-oriented programming coming to Java?
-The author was excited because they had no prior understanding of what data-oriented programming entailed and were interested in exploring this new concept after reading an article by Brian Goetz.
What is the fundamental difference between object-oriented programming and data-oriented programming?
-Object-oriented programming focuses on using encapsulation to create boundaries within an application and relies on the 'tell-don't-ask' principle, whereas data-oriented programming is centered around the data itself and how it is transformed, often using data structures that are optimized for operations like map, filter, and branch.
What are the three basic operations that can be performed on data streams according to the data-oriented mindset?
-The three basic operations are filter (removing data), map (transforming data), and branch (splitting data into different paths).
How does data-oriented programming affect software architecture?
-Data-oriented programming can lead to a cleaner object graph by separating use cases from data, allowing for the creation of components for each use case and passing data as arguments to these components. This can result in better scalability and maintainability.
What is the 'tell-don't-ask' principle in object-oriented programming?
-The 'tell-don't-ask' principle means that instead of asking an object for its data and then acting on it, you should tell the object what to do, providing it with the necessary information to perform the action itself.
How does the use of records and sealed classes in Java support data-oriented programming?
-Records and sealed classes provide a way to encapsulate data and define restricted sets of classes that can extend an interface, respectively. This allows for more compile-time safety and cleaner pattern matching, which are beneficial for data-oriented programming.
What is the advantage of using pattern matching with sealed interfaces in Java?
-Pattern matching with sealed interfaces allows for compile-time safe branching operations, enabling developers to handle different cases based on the type of data without the need for a default case, thus reducing the risk of runtime errors.
What is the relationship between data-oriented programming and the gaming industry?
-Data-oriented programming is popular in the gaming industry due to its focus on performance optimization. By using data structures that are optimized for certain operations, games can achieve higher frame rates and better performance.
What does the author suggest about being a 'better programmer'?
-The author suggests that instead of strictly adhering to one programming paradigm, programmers should be pragmatic and use a combination of tools and approaches that best fit the situation, including both object-oriented and data-oriented programming where appropriate.
How does the new pattern matching feature in Java 21 impact the use of polymorphism?
-The new pattern matching feature in Java 21 allows for a more expressive and safe use of polymorphism by enabling developers to branch logic based on the type of an object without needing a default case, thus enhancing compile-time safety and code readability.
What is the speaker's opinion on using mutable state in programming?
-The speaker prefers immutability because it reduces cognitive load and makes the code more predictable. However, they acknowledge that mutable state can be used for performance reasons, but it should be contained within function scope to minimize its impact on the rest of the program.
What is the speaker's view on the adoption of data-oriented programming features in Java?
-The speaker believes that it will take time for the community to adapt to these new ways of thinking, as Java has a legacy of a different mindset. They also mention that while Java is slowly adding features that are present in languages like Scala, it may not be as powerful or as easy to use for functional programming as Scala is.
What does the speaker suggest about the use of builders in Java?
-The speaker is not a fan of builders because they can lead to a loss of compile-time safety. They prefer immutable objects by default and suggest that Java's newer versions may provide better ways to handle immutability.
How does the speaker compare the use of sealed interfaces in Java to similar features in other languages like Scala?
-The speaker notes that Java's approach to sealed interfaces is a step towards features that have been available in Scala for a long time. They also mention that Java allows for more flexibility in terms of file organization for sealed interfaces and records.
What is the speaker's advice for developers who are considering whether to stick with Scala or explore Java further?
-The speaker suggests that developers can do functional programming in any language, including Java, but acknowledges that Scala provides more powerful features for this paradigm. They encourage sharing knowledge and learning from those who have experience with these features, regardless of the language.
Outlines
🤔 Exploring Data-Oriented Programming in Java
The speaker expresses excitement about data-oriented programming coming to Java, a concept they initially didn't understand. They recount their journey of discovery, starting with Brian Goetz's article and moving through various talks that focused on new language features like records, sealed classes, and pattern matching. The speaker clarifies that the talk isn't about how to use these features, but rather about the 'why' behind data-oriented programming. They emphasize that it's not a superior method but a different approach with its own set of trade-offs, compared to functional and object-oriented programming. The talk aims to answer the question of what data-oriented programming is and how it can make applications more scalable, ending with a nod to Brian Goetz's advice to be a better programmer by not being dogmatic and having a versatile toolset.
📚 Understanding Object-Oriented vs. Functional vs. Data-Oriented Programming
This paragraph delves into the differences between object-oriented programming, functional programming, and data-oriented programming. Object-oriented programming is characterized by encapsulation and the 'tell, don't ask' principle, focusing on methods rather than data. Functional programming is depicted as a series of functions chained together like dominoes, emphasizing composition. Data-oriented programming, in contrast, is all about the data, viewing it as streams and transformations. The speaker uses the car example to illustrate the object-oriented approach and contrasts it with the data-oriented mindset, which would de-emphasize the class structure in favor of the data itself. The paragraph also touches on the inefficiencies of type mapping and the benefits of using data structures like hashmaps and lists for operations like map and filter.
💡 The Data-Oriented Mindset and Its Impact on Software Architecture
The speaker introduces the data-oriented mindset, which views applications as data streams and transformations. They explain that most applications can be abstractly modeled using filter, map, and branch operations on data. The paragraph discusses the state changes involved in applications, such as transforming JSON to a hashmap and back, and how this can be streamlined in a data-oriented approach. The speaker also touches on the benefits of denormalizing data for performance, using the 'persons' class example to illustrate different data representations. They highlight the trade-offs between maintainable structured code and fast, performance-optimized code, particularly in the gaming industry, and how data-oriented programming affects software architecture by keeping use cases separate from data.
🔍 Case Study: Object-Oriented vs. Data-Oriented Design in Java
This paragraph presents a case study comparing object-oriented and data-oriented design approaches in Java. The speaker uses the example of implementing a 'save' method to illustrate the complexities that can arise in object-oriented programming, such as dependencies and testing difficulties. They contrast this with the data-oriented approach, where use cases are separate components that receive data as arguments, leading to a cleaner object graph and easier scalability. The speaker also discusses the implications of removing use cases and the benefits of this approach in terms of maintainability and reducing the risk of application bloat.
🛠️ Utilizing Java's New Language Features for Data-Oriented Programming
The speaker discusses how to apply data-oriented programming in Java, focusing on the use of new language features like records, sealed classes, and pattern matching. They explain polymorphism in the context of data-oriented programming and provide an example of implementing the strategy pattern using these features. The paragraph explores the benefits of using pattern matching with sealed interfaces for compile-time safe branching operations, which is a game-changer for control flow in Java applications. The speaker concludes by emphasizing the importance of being a better programmer by using the right tools for the job, rather than adhering strictly to one programming paradigm.
🔄 The Evolution of Java's Approach to Polymorphism and Data Streams
The speaker reflects on the evolution of Java's approach to polymorphism, discussing the introduction of new features that enable a new way of using pattern matching and sealed classes. They highlight the impact of these features on data streams and state changes within applications. The paragraph also touches on the community's adaptation to these new features and the importance of understanding type theory concepts like product types and sum types. The speaker anticipates a period of adjustment as developers become accustomed to this new paradigm in Java.
📘 Navigating the Transition from Mutable to Immutable State in Java
In this paragraph, the speaker discusses the transition from mutable to immutable state in Java, emphasizing the cognitive benefits of immutability. They argue that immutable objects simplify software engineering by reducing the need to understand the entire program to ensure consistency. The speaker also addresses the performance implications of mutable state and suggests that functions should ideally have immutable inputs and outputs, with mutable state confined to the function scope. They express a preference for immutability and caution against the use of mutable state, advocating for careful handling if it is necessary.
🔍 Discussing the Use of Builders and Records for Immutability in Java
The speaker engages in a discussion about the use of builders and records for achieving immutability in Java. They express a preference for records due to their simplicity and the default immutability they provide. The paragraph explores the trade-offs between using builders, which can offer a more fluent way of constructing objects but at the cost of compile-time safety, and records, which enforce immutability. The speaker also mentions upcoming Java features that will further support immutability and improve the quality of life for developers working with immutable objects.
🤝 Sharing Knowledge and Adapting to New Java Features
The speaker concludes by emphasizing the importance of knowledge sharing and adapting to new Java features. They encourage experienced developers to share their insights with the community, particularly regarding advanced features like sealed interfaces and records. The paragraph also touches on the ongoing addition of features to Java that have been present in other languages like Scala and Kotlin, and the need for Java developers to continue learning and evolving their skills. The speaker expresses optimism about the future of Java and the opportunities it presents for developers to grow and contribute to the community.
Mindmap
Keywords
💡Data-Oriented Programming
💡Object-Oriented Programming
💡Functional Programming
💡Polymorphism
💡Records
💡Sealed Classes
💡Pattern Matching
💡Immutability
💡Cognitive Load
💡Strategy Pattern
Highlights
Introduction to the concept of data-oriented programming and its distinction from traditional object-oriented and functional programming paradigms.
Excitement about Brian Goetz's article on data-oriented programming coming to Java, which sparked a deeper exploration of the topic.
The importance of understanding the 'why' behind software engineering concepts rather than just the 'how'.
Data-oriented programming's focus on data streams and transformations as the core of application development.
The comparison between object-oriented and data-oriented programming in terms of handling data and operations.
The debate between functional programming and object-oriented programming, emphasizing the need for a flexible approach rather than being dogmatic.
The role of language features like records, sealed classes, and pattern matching in facilitating data-oriented programming.
The potential of data-oriented programming to improve application scalability and maintainability.
The practical application of data-oriented programming in enterprise software and the gaming industry.
The impact of data-oriented programming on software architecture and the benefits of separating use cases from data.
The discussion on the trade-offs between performance optimization and long-term maintainability in software development.
The use of pattern matching with sealed interfaces and records in Java to implement compile-time safe branching operations.
The comparison between Java's new language features and existing capabilities in languages like Scala and Kotlin.
The importance of being a 'better programmer' by utilizing various programming paradigms and tools as appropriate for the situation.
The future of data-oriented programming in Java and the community's adaptation to new language features.
The call to action for programmers to share knowledge, mentor others, and contribute to the growth of the software development community.
The conclusion emphasizing the need for pragmatism in software development and the value of combining different programming approaches.
Transcripts
and I'm quite big on software
engineering fundamentals and Concepts so
more about the why instead of the how
those are things that get me
excited um that's why when I saw Brian
gats write a article about two years ago
now about data oriented programming
coming to Java so I was quite excited
because I had no clue what data oriented
programming actually meant um so I
wanted to figure that out and I went
searching online and I quite found quite
a few talks and most mention these new
language features records Shield classes
and pattern matching which in off
because these are the things that should
make this data oriented programming
possible however basically all talks I
found were about how to use these new
language features and that's why I don't
want that to be the main focus of this
talk because I needed answer to the
question so what actually is data ored
programming
and because I couldn't find the answer
of the talk online then I figured oh for
the question online I figured then I'll
just write my own talk about it so
although we'll go into a few language
features at the end and that's not the
main purpose of this talk and something
that's important to me uh that this is
not a better way of programming it's a
different way of
programming um there's a lot of debate
between functional programming and
objectoriented programming and such and
for me especially as someone who's more
into fundamentals uh in the end it's all
engineering and both ways have the
tradeoffs some work better in certain
areas other things will work better in
other areas so this is not a better way
of programming it's a slightly different
way of programming and one which you
might already do Brian gats has a really
good talk function programming object
oriented programming pck two and he
ended with this quote don't be a
functional programmer don't be an object
a programmer be a better programmer and
I think this this for me this was quite
inspiring as in no we shouldn't be
dogmatic uh we should get as many Tools
in our toolbox as possible so we are
prepared for every situation and we can
write the best possible solution for
every occasion so what are we going to
talk about today we're going to do a
quick recap about objectoriented
programming functional programming data
oriented programming what it actually
means then we'll head into the data
oriented programming mindset programmer
mindset
um we'll take things to a bit of an
extreme there but it's just to get a
picture of what it's like to see data as
data then we'll go into what data
oriented programming does to our
architecture and how we can use it there
to make our application more
scalable and then we finish off with
talking a bit about what the language
feature actually means the new language
feature actually means and what this
allows us to do so let's talk with
objectoriented programming versus
functional programming versus data
oriented programming so uh what's object
oriented program programming well here
everything is an object and it uses
encapsulation to create boundaries
within your application and it relies
heavily on the tell don't ask principle
so what do I mean by that it means if we
would have some code like this where we
have a car with current Fuel and a Max
Fuel and some Getters and Setters if you
would have a function add fuel that
takes a car's input here we ask the car
for the current Fuel and we ask the car
for the max fuel and then we set the
curent the current view this is not
really the object oriented programing
mindset because here we ask the object
for its data instead in object oriented
programming we want to tell the the
object what to do we want to tell the
car to add the fuel and just give the
amount and how it solves it we don't
care we just tell it what to do we don't
care about the data we care about the
methods put that more in perspective if
we would have a class data we actually
don't care about what What fields it has
we care about what are things we can do
with this car object if you then look at
functional programming uh here's
everything is a function uh a good way
to symbolize that uh and they're tied
together using something called
composition good way to visualize that
are dominoes where every stone could be
seen as a function which has a number as
input and a number as output and as long
as the number output matches the input
of another Stone you can chain them
together you can create really beautiful
software that way that's the basic
Parise of functional programming so what
is data or programming uh well here
everything is data or more specific
everything is about the data so if you
would have any class within data or
programming we don't actually care it's
in a class we just care about these two
Fields because that's the actual data it
just happens to have something called a
car wrapped around it but we don't care
about that stuff we care about what's
inside the car what are this the data we
can work with and this brings us to the
data oriented Pro
mindset um so here data mindset it's all
about the data to visualize that bit uh
if you take a big enough step back like
and look at applications in a really
abstract way most applications are just
data streams and data streams are
nothing more than data transformation so
data streams is nothing more that you
have a source which something that emits
data and a sync something that receive
data and the nice thing is there are
only basic three operations you can
perform here there's a filter that takes
data away from a scen there's a map that
changes data to another type of data and
we have a branch that either says uh
splits up the data uh in one way another
way or just splits it up evenly and
using this way of thinking you can
actually model basically every
application out there to give an example
if we would just look at any web service
we would have some Json that gets mapped
to the user a user might need to go we
might need to check some permissions
which is a filter operation because
everything might stop there then we
might find a filter the user out because
it it doesn't come through our
validation phase and once everything is
done we map the user to a query we M the
query to an entity and we map The Entity
to response and we map the response back
to Jason so if you look at any
application abstractly enough it's just
a data stream that goes from Json
through this back to Json uh using only
map and filter operations so there's
also a lot of State changes going on
here it go from user to query forr to
entity for entity to respon and response
to
Jason and usually in Java we use types
for is so we go from Json to hashmap
from hashmap to user from user to entity
enti response from response to hashmap
and from hashmap back to Json and that's
quite a lot of types for quite a simple
operation and this is where a real data
oriented programmer thinks huh that's
not very very good because types also
have a downside as types don't naturally
map well to other types so uh if you
want one type to map to another type you
usually have to write a custom mapper so
if you make a class person and want to
turn it into a second person you would
need to write a custom mapper or you
have to use reflection for example uh
spring boot uses Jackson as Jackson for
Json calization which US under
reflection under the hood working with
types either means you have to write
custom code to map one type to the other
or you have to rely on reflection magic
to do it so types don't map well to
other types and this is a problem
according to data oriented programmers
because that's most of the things we do
we map types to other types fav types
don't M natur you map to other types uh
so data programmers are like why
shouldn't we use uh data structures that
are made to do these things like hashmap
or List these are data structures that
are meant to do operations as as map and
filter and such uh on the data structure
itself so if would instead of that use
hashmaps it would look something like
Json to hashmap to hashmap to hashmap to
hashmap to Json which is a lot easier in
a way we don't have to write uh classes
for intermediate data uh representations
you can just go from Json to hashmap
then it's hashmap all the way back to
Json so that's basically thinking in uh
it's just data we don't care about the
types we only care about data and data
transformation so does this mean that we
should just stop using types uh well not
really like real data oriented program
languages like closure they can get away
with this uh because in closure you have
things like um schemas where you can
basically tell that the hash should have
at least these keys and they circumvent
certain problems by just writing a lot
of tests and this is where types shine
because types gives a lot of comp time
checks and therefore we have to write
lot less test because we are certain
these fields are there because we use
the type system so in Java I wouldn't
recommend going uh all hashmaps but we
can learn something from this way of
thinking we don't have to model our data
in that structured way it can also uh
denormalize data and that can have some
benefits as well to give an example of
that um if we have a public class person
which has a age and a name if you would
have a bunch of person we could put them
in a list and this is nice and ordered
we have a person and we have a list of
persons a way to denormalize this data
would be our class persons which
contains two lists one containing the
ages and the other containing the names
so these are two ways to represent the
exactly the same data where this is nice
and structured and this well I don't
really like you would normally really
like this uh representation but it can
have some benefits and that really shows
when you look at for example
databases where if you make a database
for your own software or database
designed for your own
software you want everything to more
look like this everything should be
dormal normalized uh there shouldn't be
duplication everything should be nicely
checked from keys and everything so the
database can protect you against
mistakes and protect you against data
corruption uh but it has a downside is
that relatively the queries are
relatively slower than they could have
been and so if you would give your
database to a data warehouse they would
do really really bad things to that data
as in they would duplicate everything
create massive tables uh but they're all
optimized to do certain searches which
are lightning fast so by giving up all
the structure and all the duplication as
such we get a lot of performance and
this is also what we can do in code
instead of having nicely structured code
which is optimized for
uh longer term maintainability we can
also go for different representations of
the same data and have it to be lighting
fast uh where you see this a lot is the
gaming industry for example because in
the gaming industry you want want that
60 FPS so uh doing every trick in the
book to make sure you get to that uh
that's important there there is also a
bit of a different distinction where the
tradeoff of uh long maintainable code
versus quick code uh tends to lead more
towards quick codee with gaming because
even though the statement isn't that
true these days uh but once the game is
finished you don't really do more
patches on it while enterprise software
will get a lot of Maintenance over the
years so the trade of of or we rather
have fast code than than code we have to
maintain um in gaming that leads more
towards the fast code while Enterprise
software would Le more toward structured
code but if you have struggle somewhere
with uh performance well these are
tricks that you can do uh so that's what
the reason why data programming is very
popular within um gaming within the
gaming industry so aside from
performance um data oriented programming
also affects architecture so let's see
how we would design something in
objectoriented programming versus the
data oriented programming way in
objectoriented programming uh all the
use cases we together with the data as
you saw we have this tell don't ask uh
principle
where our car would have method set VI
and this makes it very easy to see what
operations are available on that data in
data programming we don't care about the
class we only care about the data and
therefore use cases will live separate
uh in separate components so they won't
be directly connected to the data which
does give a clean object draph and can
scale better uh to give an example of
that uh let's implement the S the save
method in an objectoriented programming
tell don't ask way so we tell a person
it needs to persist itself in order to
do some do persisting we would need
something like a data access Helper and
there are three ways to do this one is
that a person would get a data access
helper for its Constructor so when call
the safe method it can use that data
access help the problem here however is
now construction of the person becomes
way more difficult aside from all the
data you also need to give all the
dependencies uh for all the side effects
that the person needs
we could of course cheat this and use a
static lookup instead which would work
uh but now it's very very difficult to
mock this which is also not very good so
this makes it a lot more difficult to
test or finally we could try a more
visitor pattern approach where we would
pass the data access outut to the save
function but now both the corer both the
corer of this function and the person
needs to know about uh how this object
should be persistent which is also not
good but the bigger problem here is that
all three methods uh rely on the person
class to have knowledge of the data
access help so if you would put this
into a diagram a person would now be
dependent would now be dependent on the
Exel but a new component would be
dependent on the person but because
person has this dependency transitively
the component is also dependent on the
data access out and if it's just this
then it's probably fine but what if we
need to add a second component component
which needs needs to do something with a
person that involves a rest controller
then our object graph would look
something like this the first component
needs to do the person to do something
with the data exess helper the second
component needs the person to do
something with the rest Helper but now
trfy both components are dependent on
both the data access help and the rest
helper so we started creating a bit more
of a net here also what if we don't need
this component anymore this use case um
this use case doesn't exist anymore we
will remove this will we actually also
remember to remove all the codes within
person that was needed for just that use
case uh because you probably wrote test
for this I assume and
therefore the IDE won't show you those
methods are no longer in use so since
the person class slowly would get bigger
and bigger at some points it's quite
like you forget to remove these methods
which means that it will have become
even bigger than it should be so there's
a bit of risk in there as well like I
said the chances of application
shrinking are not that big most
applications only tend to grow so the
amount of use cases will increase and
therefore our object cses will increase
as well we just keep adding more use
cases to for example the person class
and I've seen this happening I worked at
a company where we had a bit of software
that was already uh in development for
15 years and we had this exact produ
that a few of our core components were
getting massive with all the use cases
it had to support um so how can we solve
this uh using data programming uh in
data programming again we don't want to
mix the use cases together with the data
so the only thing we can do is we create
a component for every use case and then
we pass the data as argument to that
component so that would look something
like this where we'd have a person
persistor which would take the person as
data and then just save that person so
the person doesn't know uh that it's
being saved that's just a bit of data
this use case decides to save the data
using a data access Helper and if you
would look at how that would look within
um our independency graph it would now
look something like this where the
component that needs data access helper
is depend on data access help and it's
dependent on person but person doesn't
know it's being used by the data access
helper so what happens in this case when
we add a second component which needs
that rest helper now would look
something like this where this component
only knows the data exess Helper and a
person and this component will only know
the rest Helper and this person and the
person doesn't know anything so our
object graph is way way cleaner this way
so what if we remove a use case oh now
we can just remove that component and
all the logic containing uh to the juice
case has now been deleted of course we
could still forget to delete the whole
rest helper thing uh but at least this
this doesn't harm things in any way this
is just a separate bit of code that
doesn't get C anymore uh but it's not
part of your big uh big monster of O CL
anymore so worst case scenario uh this
isn't that bad and can even be reuse in
the later at a later point and if you
now think this kind of looks familiar uh
well if you write this boot application
for example this is kind of what you
already do you take some data you pass
it for example to a service and the
service will persist that data so you
don't build a safe method on that data
that on the data that you pass to the
service you do that within the service
and for me that was quite a revelation
that I've actually been doing data
oriented programming for years and years
now I just didn't know that's this was
being called Data ored programming and
wasn't actually object oral
programming so if you use any Frameworks
like spring Micronaut or quarkus or
something you probably already do things
in a data oriented programming style
which which I found to be quite
interesting and it also shows that oh it
it actually works so should you not just
not use object on your program anymore
uh no not really that again it's just a
tool in your toolbox and just be a bit
careful with how your dependency tree
will turn out to be and therefore why
you apprach your business logic but most
importantly uh be pragmatic and not
dogmatic do whatever works best for your
application and it might even be a
combination of the two and that brings
us to the final bit of my talk um how
does the how can we do these use these
things in Java and like I said I don't
really go that much into the language
features itself uh but I'll try to show
the idea behind using those language
features because the biggest part we
have uh that all these things added is a
new way to use morphism within Java
polymorphism is basically if one object
extends another thing uh now it's both
types therefore it's
polymorphis so polymorphing is just a
fer for if some one type extends another
type and for a long time in Java this
was mostly used to share code but right
now with the new Java one language
features we can also have a lot of
benefits for just sharing
types uh an example of this is uh using
the strategy pattern first in an object
oriented programing way and then we'll
see how we can build the same strategy
pattern now in a data oriented
programming way so the strategy and
object programming means you have an
interface for example credit card which
has a method pay we can have two
implementations of of this credit card a
Visa card and a Master Card and both
have a dependency on the actual thing
that the side effect that does the
payment so Visa card has a dependency on
Visa card payment and the Master Card
has a dependency on MasterCard payment
and a component only knows the the use
case component only knows the interface
so to put that into code uh we have one
interface credit card which a method pay
a Master Card implements a methods pay
in its own way and a Visa card
implements a method pay in its in its
own way and now the logic component gets
any credit card it doesn't know which
one but it does know it can just call
the pay method and the really nice thing
about the strategy pattern that it's
fully compiled time save if I would ever
add a thir credit card uh the interface
forces it to implement the payment
method so this du logic will work on any
credit card I would ever add into my
system fully compiled time safe so my
compiler can really help me here so this
way it skills really well because I
don't have to change basically any code
if I add another credit card however um
it does force us to have our payment
methods together with our data so let's
see how we could do the same in data or
program so what we kind of want to
create here is we still have an
interface credit card which is either a
Visa card or a Master Card but we want
to remove all the logic and towards the
component so now the component should
know the Visa card payment and the
MasterCard payment so to do this we can
use Java's new records uh where we
create the interface credit card and
since we don't actually need any methods
whatsoever we can just use a record
because it only holds data so it only
holds a the credit card number so it
creates a record for Visa card and a CR
record for MasterCard and this is where
Java 21's switch statement comes in so
we can now pattern match over the credit
card and do an instance of check so in
case it's an instance of MasterCard we
put it in the variable MC and then we
call the MasterCard payment component to
do the pay the payment if it's an in of
Visa card we put it into this variable
and it can say tell the Visa card
payment to do this and for a very very
long time um this was the reason why we
don't really use this pattern a lot in
Java because we have to have a default
statement here what if another credit
cards get added uh then we will
automatically go into the default mode
and this is why um reduce all the
compile time safety that we had with the
previous strategy pattern because if I
add another credit card I will get an
eal State exception here well with the
previous pattern uh if I would add in
object oral programming if you would add
a credit card there it would always work
to overcome this ja introduced the
sealed keyword so you create a sealed
interface credit card which permits Visa
card and MasterCard so basically we tell
the compiler here the only two possible
implementations of this credit card is
either a master card or or a Visa card
and there are no other implementations
and because we told to compil this
information if we P match over a sealed
interface we now get this we don't need
the default anymore since the compiler
knows these are the only two possible
implementations it will even Auto uh
like if you use intell or something it
would even with old enter complete the
whole pattern match for you because it
knows which are all the possible
implementations of the credit card
and if it would ever add a credit card
in the future or remove one this switch
statement no longer compiles so finally
we have our compile time safety back
again so we can actually use this
pattern so until Java 21 we didn't
really have the option to do this but
during Java 21 what we actually finally
created was our branching operation
because that's what we're doing here
given a credit card we either go one
route or we go another route and and
this is really really uh good since we
can not not just use this for credit
cards also think for example oh we get a
contract if it's a signed contract go
this way if it's unsigned contract go
that way you get a result from a
function it either succeeded or it
failed we can use this pattern matching
uh for all kinds of purposes and that's
why I think this is really a game
changer this is a new way of using
polymorphism we didn't have access to
until before Java 21 uh which also means
um it will I think take a while before
we get used to this because this is a
feature that has been in for example
Scala a lot for a very very long time
and it it's also there in cotland uh but
in Scala basically people don't write
write if statements anymore basically
everything is done through sealed
glasses and patter matching to predict
all to do all the flows and this also
really helps you in thinking in state
changes so I said um in the beginning uh
when you think about an application it's
mostly data transformation which is just
State changes for example like I said uh
a contract is it's signed do this if
it's unsigned do that so with Java 21 we
actually have a whole new way of using
polymorphism and if you find it
interesting I can tell a little bit more
about that um after I finish the talk
but in conclusion of uh data program in
Java
is most applications are just data
streams if you look at them in a very
abstract way um and data streams only
have a map and a filter and a brand
operation and it's basically just State
Changers through data so why have types
you could use hashmaps as well and this
can be beneficial for performance uh for
performance increases uh by separating
States from functionality we can offer
some better scaling because we can
create components for every use case
instead of all the use cases having to
live into side a single component and
thanks to um the new patter matching
with instance of and SE classes we now
have a game changer U with compile time
safe branch operations and with that I
would slly like to end uh with a
slightly adjustable quote from Brian
gets uh don't be a functional programmer
don't be an object programmer don't be a
data oriented programmer be a better
programmer don't just write hashmaps
everywhere right now uh all these things
all these ways of thinking and using
there are just Tools in your toolbox uh
and most of often It's a combination of
all three uh that's why we get the best
out of your software um and with that uh
that's the official talk uh if you have
any questions we can go into those now I
can also tell a little bit more about uh
the what kind of big deal the new
pattern matching thing is uh if you guys
like uh if you have any questions uh
later you can add me on Twitter or X as
it's been called now or LinkedIn I'm
actually a bit more active on LinkedIn
also have a website if you want to see
any slides of me uh of all my talks or
uh any recorded talks they will all come
on this website so this talk has been
recorded on Heaton before he before so
that's also a way to look it back I do
want to give some attention to this uh
this is a website I'm also a member of
um it's a place where people can either
offer to Mentor others for voluntarily
or you can look for a mentor uh so
everything is unily uh no cost to any
party and I already helped like five or
six people there and it's just a really
rewarding feeling if you can help
someone so if you have any skills and
think you can help if you can help
someone else please register as a mentor
otherwise if you're looking for a mentor
um you can go to that website as well I
like I said I'm quite bit big on
knowledge sharing and I would like to
have this kind of knowledge accessible
to as many possible people uh and most
of the skills I possess now almost all
come through teaching others so it's a
really good investment not only in
others but also in yourself and if you
just want to see the sheets you can find
these on this URL so with that are there
any
questions s Kumar here I think there are
a couple of questions Raja has a
question so before that I will go with
mine uh so um considering that this data
oriented programming can work with the
latest version of java that is only when
we use sealed classes and record which
is a recent Edition and how do you see
the how do you see the adaption uh of
these features because uh the community
itself is lagging right most people will
are there in 11 only so for an existing
programmer in your team did you find any
any problems or how is it actually that
option um the thing is that uh well
first of all for any Paradigm you
actually don't need that many language
features um it's like just with
functional programming like Java can do
functional programming very very well
you don't need a Scala to do that it's
more of a way of thinking and applying
those patterns and of course some
languages do things more easily than
others like without SE classes this
stuff becomes a bit harder to do um and
the thing is that I think it will using
this sealed class SP Manching I think it
will take a long time before we actually
start using it because people don't know
this way of thinking um
because uh well we we can go a little
bit into um uh Theory because up until
then this is a completely new thing in
Java um we have something called type
Theory where you think about types and
we have this very fancy word uh called
uh an ADT which stands for altic data Ty
type which is just a fancy word for an
immutable object and you have two
different immutable objects two
different kinds of altic data types we
have product types and we have some
types um product types are just like if
you would make any uh immutable class
you were probably making a prodot type
so what do we mean with that a person is
for example has a name and an age so if
you want to create all possible persons
you have to do all possible names times
all possible ages so it's a product of
all names and all ages so this this is a
product type uh a different way um to
see that is this is a and type a person
is a name and an H A some type is an or
type or type is for the only thing we
had in Java uh was an enim for example
it's uh
Monday uh or Tuesday uh and it can't be
either of them so it's this one or this
one this is what we call a some type
thanks to sealed glasses we can finally
have other some types instead of enm in
Java which means that for example the
Java optional uh could now be
reimplemented uh as a seal type using uh
none and some as um which now if you
return an optional it's either an
instance of none or it's an instance of
some containing something which allows
you to do the whole branching pattern
matching over it so this is for example
how language like Scala does this kind
of stuff
yeah I should sorry I just read chat
this is for example how languages like
Scala do it all the time but this
feature has been in Scala from the start
so they had years and years of
experience in this way of thinking and
Java 2 we just had this like Java is
what 25 years old now or something we
never had this before so we have this
whole Legacy of thinking not in this
part not in this way of thinking so now
we finally get to death point Point um
so I think it's going to take me a while
before we adapted our way of thinking to
see how powerful this way of working can
be yes yes and just curious maybe I my
question may be stupid question so um
can you tell me the the use cases where
you see you can see some immediate
benefit for example is this relevant to
our or related items where we interact
with databases do you see data oriented
programming will have an impact on these
core fundamental areas in interface
appli
in what kind of in Enterprise
application uh object relational mapping
database jdbc interactions and all those
stuff where we do lot of data
transformation um in practice I don't
think so um I see this way more as a the
control flow of your software will can
be quite different in practice I don't
see um all the reflection being changed
Going to hashmaps and such and this
stuff doesn't really
help a lot with object relational
mapping so in practice in most
enterprise software I don't think people
use it in that way um however uh using
some types and using Des for control
flow like using the branch operation
based on type I think that's going to be
a thing um I already started using that
in some applications and people who
didn't know the concept uh didn't
actually need that much explanation to
see oh this is actually quite useful
uh also in practice it's very easy to do
since most interfaces in most G most
even class or interfaces that you create
can become sealed it doesn't have any
downside of making them
sealed um since you're not really using
the like if if you have a library um you
can even use it to add compile them
safety uh because you can normally you
have to make classes final and such to
prevent others to extend it now with
seals you you have a different way to uh
prevent people from extending from it so
I'm yes thinking out loud uh so it might
not be completely organized all right so
I see can we add annotations to
parameter of record class oh yeah yeah
that works if you have a record uh that
just works uh I just saw this
question we can name the method to say
FEA pay in the dator approach um I don't
that would break the pay comes from the
interface so that would break the
interface so I don't really fully
understand the question yeah can you
show me that slide where you had switch
case yeah okay yeah you're saying credit
card is still an interface then why
should I even put a case and then call M
mastercard. pay I can directly call
credit card.pay right
um yeah uh why by you put it in a
separate variable yeah instead of two
switch cases yeah uh yeah well um if I'm
depending only on the credit card
interface yeah in this case M Vis don't
have any uh yeah as in you uh don't have
any uh methods by itself so right now
this is doing all the logic and this all
this takes only a MasterCard which
that's why we need to do uh pattern
matching on instance off so which means
you know the question I asked you know I
can name this Visa card in the different
method name um yeah which which method
are you referring to now the second case
you mean this thing uh exactly I can
yeah I oh yeah yeah yeah but this this
is uh okay then I B this is just a
dependency of the component that calls
this this right now it's a um static
call so this this is something different
from this
um this could be called Visa pay if you
like but for this example it wouldn't
make a difference because any credit
card is just a record it is yeah yeah
this is just a record and this is just
data that's being passed to basically
this is in case it's a Master Card I
want you to do this with a Master Card
if it's a Visa card I want you to do
that with a Visa card oh T I have one
question on this right so um given that
record is more often we we will be using
mostly
uh in the data classes which are more of
an immutable in nature right
most now given that we also have
something called as a builder where we
also try to do some immutable classes
there as well with the state what you
state we Define the Builder and we just
pass on the different attribute that
will become my once object I can't modif
so with the builder as we try to a the
immutability there although it gives a a
better fluent way of building the
objects with the optional But ultimately
it provides me the immutable objects
right now
I I have the debate on the these two
things now whether you should go with
the record class in that Cas or whether
to go with the builder classes
on yeah um this is all on immutability
and Java is not good in immutability
right now um one thing that uh ROK does
add it has inde an add Builder
annotation I personally don't like
Builders uh because that's uh uh in a
lot of cases it's a missing language
feature since Builders uh allow you to
build an object without passing all the
the properties it needs to pass and then
it will fill at runtime which means if
you call a Constructor if you would add
something to that Constructor you now
get a compilation time check that this
is not going to work or these are the
places where you need to fix something
uh by using a builder you lose that
compile time safety so that that's the
bit what I don't like about Builders um
that being said lbox builder at Builder
has uh something where you can take an
existing object call a two Builder
method on it and then you can set one
property to be different and then call
build again that would work but in Java
we will get a better way to do this in a
newer version of java and
basically chains only one property of an
existing object uh if it's a record so
this way um we do get around a bit about
bit of um Quality of Life features
regarding immutable objects so this
stuff like this is coming in Java okay
does that help bit in answering your
question bit of help there yeah uh I had
one debate yesterday with my senior
person and and his thought also valid I
just want to get your opinion one of the
question that we have we have been
discussing in PR if you look at the past
we now if you look at the oriented
program as well where we Define a data
model we Define some attributes and then
we say okay at theate getter at theate
Setter we Define the get Setter and
whenever I need that object I just use
the get method get attribute and then
set attribute right now yeah if you
think of the data programming we
generally used to have this set method
get method where you want to have some
control over my attribute that I'm going
to set from externally to model where
you can write some business logic to
validate my some of the values that I'm
passing it right that was a intentional
in in in the past nowadays it's more
about just transforming the object one
state to another state one object to
another object just setting of those
some attributes right um and rather than
having this Setter and getter methods
itself why not to have but object dot
attribute name is equal to something
some different value set meth because
now noways it's just the data
transformation is just only holding the
object for temporary my purpose and then
I'm transforming to different state with
a different model all together right so
he has a thought that okay if you're not
writing any business logic it's just a
data model that I have he he likes to
write okay the object do attribute name
is equal to something it gives more
readability as well in terms of it and I
know that there's not going to hold any
business logic it's just as a Val I'm
going to set and just passing along the
my different functional or different use
cases so yeah so I just want to
understand your thought on this model of
parad that's what they trying to say say
p do set name he doesn't like it but he
he WR but he like but like he like this
this way yeah I I don't like mutable
State um since it's almost five um the
thing what I hate about mutable state if
our car here was a mutable car and we
have this bit of software where I print
out the car I pass the car to my paint
method and then I print out the car
again do these two things print out the
same color we don't know we don't know
if if the car is mutable we don't know
if this method changes it or not so the
only way to know is going into this
method hopefully see it there and hope
that method doesn't call another method
with the car such as in we need to know
quite a bit of our software in order to
know if these two things print out the
same thing if we however would create an
immutable car and now ask the same
question do these two Sprint out
statements print out the same thing the
answer must be yes because the car is
immutable correct so this is where
immutable objects really reduce the
cognitive load of software engineering
because I can instantly say information
things about this code uh that has to be
true and I don't have to read everything
that this does uh the downside is yeah
if you want to change values you have to
create a new instance but which means
you have to return something what
happens now is if you now ask question
do these two things print out the same
thing probably not because you can see
the state change going on here because
it needs to be a return value of this
function uh therefore uh or you can
either instantly tell uh nothing changed
or you can immediately tell something
must have changed and this is what I
really like about reducing cognitive FL
uh by using immutability uh because if
things are mutable uh yeah you don't
know where in the software variables can
get set which means you can't rely on it
which means you have to know have to be
in control of your entire program well
here I can instantly see oh I probably
need to maybe check some things after
this or at least see a state change uh
has taken place so I don't like mutable
state it has it it has some uh benefits
in terms of um performance uh but if
you're going to do mutable state for
performance sake I kind of like my um
functions to have an immutable state in
and an immutable object out and only mut
mut all the mutable state is within
function scope uh this way the mutable
State doesn't escape this function and
therefore the rest of the software um
can think in terms of immutable in
immutable out and has all the safety of
immutable software of immutable objects
so in this case because this mutable
variable and this mutable thing doesn't
escape the function the rest of the
software doesn't know if mutable or
immutable state is being used here I
could completely change its
implementation to an immutable one the
software wouldn't know I can change it
back the software wouldn't know so
mutable States in my opinion like you
can use it but be careful with it and if
you do it try not to have it Escape
function scope uh because that's the
point where the cognitive load becomes
way way higher than it it can be got it
got it y thank you yeah so so my I mean
pleas my understanding correct me if I'm
wrong uh my perspective toward sunil's
question is uh Sunil uh we as a
programmer very familiar with writing
mutable code right sets and gets correct
corre correct okay actually the sets and
gets when these were introduced we used
to develop UI applications in Javas
swing and all those early days of java
at that point in time sets and gets were
crucial part of our user development at
that point in time the default choice of
a language was
mutability but later as the hardware
accelerations all this modern
Technologies came people realized
particularly web publication developers
realize that immutability is the real
strength immutability is supposed to be
the default and you can break and then
go to mutability not the reverse that is
the realization that is that is the
direction where now going with record
you get immutability by default but the
drawback is your
programming uh perspective that is so
far we have been comfortable with iners
and gets which will take some time in
fact this was one of the question to the
jdk development team the answer to that
question is that the person was so
critical the one who implemented it he
simply said no it is supposed to be done
in this way but again again and again
Java Community people are asking T's
answer was actually refreshing to me
also because uh because of the community
demand I think now Java is coming up
with a new structure where they are
matching both the performance benefit of
immutability as well as that syntactical
thing they are adding something new
which is a new thing for me also because
at that point in time the team was
entirely against going with that sets
and gets again that it's not the
direction that we should go fully agree
um this talk is a very if you're
struggling with that this is a very good
talk to watch a simple mid E from Rich
hickey um because he puts it in uh a
completely different
perspective uh since simple is something
else than easy because easy is a easy
versus heart and simple is simple versus
complex so uh the thing is that if you
know something it's easy if you don't
know something it's hard so simple
versus easy easy versus hard is very
subjective that's different from person
to person uh while immutable state is
inherently simpler than uh is than IM
mutable State mutable state by
definition is complexer than immutable
state so that's an objective thing you
can't disagree with that because it's
it's it is a fact um but it's also if if
you can see in that way that this
discussion is a easy versus hard thing
uh that just means if you start using it
more and more and more if you start
learning it it will become easy so um
that that's with a lot of things where
people are like oh this is this is way
too complex or something then you have
to take look does that person mean is
it's actually more complex or is it hard
for that person because if it's hard for
that person that's something you can fix
that's that's just teachable and then it
will slowly become easy or is it
actually more complex yeah then it's
wrong because we should favor simple
approaches so this is a very very good
talk about that uh this has really
changed my view on software engineering
sure I'll also go go through this talk
definitely uh M you have a question
right you can unmute and speak yes
please goad sure yeah so my question was
more on the sealed interface so I have
experience in Escala so I I you seal
trade there so do we get um you know
more than a
in in the Java 21 feature that along
with this sealed interface and another
thing inala we Define all these in one
file and generally in Java we will have
one class in a file right so uh how do
we put these sealed interface and
Records in one file or multiple
files works that actually does it better
than Scala uh you can choose um right
now um I I did something here that
that's not fully correct
um I can omit this if it's in the same
file um I can just write it like this if
I want these things to be in different
files then you need the permit then you
need the permit keyword so with this
Visa card can be in a completely
different file and Master Card can be a
completely different file or you can
write it without this and then declare
them in the same file and that would
also work right so thank you sorry one
more followup question so like what I
see uh nowadays right so in Java so all
the features that that is there in the
cotlin OR Scala they are slowly adding
it to Java yeah so uh if if we look into
functional programming uh so I just
wanted to know your opinion uh is it uh
good to uh to still stick with Scala
because that is much more powerful and
gives more features in functional
programming so should should should
developers stick to that or should start
looking to Java side because I I think
still there are a lot of things that are
not added to the Java even at this
moment so basically that's what this
whole talk is about um that's uh about
functional programming in Java um in a
way functional programming can be done
in any language uh it's mostly a way of
thinking and a way of a certain approach
to problems and so therefore yes you can
perfectly do functional program in Java
that being said uh language features do
help with it so Scala is way more
powerful than J basically any other
language on the jvm um regarding to
functional programming so if you really
just want to go heavy into that Paradigm
Scala will help you more than Java if
you however are programming Java U the
fact that you're not using skyar culon
doesn't mean you can't apply all these
principles it's just things like
everything is knowable by default in
Java so you kind of have to do um be
what's the word um uh you kind of just
have to make sure you don't abuse that
and you kind of have to assume other
people don't abuse that but given a few
assumptions here and there you you can
still do functional programming in Java
you can always do better in Scala but
you can get not decently close in Java
these days um the thing about Scala is
that uh because it's so
powerful um uh people tend to write
things in 10 different ways because you
can write it in 10 different ways which
means that you kind of have to know
Scala quite well and it took me my first
attempt to learn Scala I couldn't get
through it then I learned cotlin and
then using that knowledge I learned SC
tried Scala again and then I could get
Scala uh but scar is is uh not an easy
language to get introduced to I do think
scar is a beautiful language yeah I do
and I was uh I mean the only only uh
thing that I felt uh many times uh
compilation is a bit slow compared to
Java that I felt otherwise the the power
the features that we get in scalar is
much better but but what I see now in
Java uh most of the you know useful
features we are getting to the Java
and yeah so I was looking into that like
whether I should Explore More on what is
coming in Java and and try to learn that
and we need people like you because you
worked with sealed classes before and
sealed interfaces you know how to use
those and most Java Engineers don't know
that so we need people like you with
experience in this to teach all the
whole Java community and show people the
power of using some types like this so
uh please share your knowledge with
other people about Scala because it's
relevant to Java people right now yeah
so thanks a lot sorry we we took extra
time from UT uh and thanks for uh the
very useful session uh it was very
useful for every one of us
Посмотреть больше похожих видео
5.0 / 5 (0 votes)