Data-Oriented Programming in Java. Data-Oriented Programming (DOP) focuses on decreasing the complexity of the Object-Oriented Programming (OOP) application systems by rethinking data, i.e., separating data and code. DOP divides the system into two core components (Data entities and Code Module), where you can think about each separately.
However, before moving to Data Oriented Programming in OOP languages like Java, it is essential to understand how OOP increases the complexity of creating a system.
So in this blog, we will cover OOP and its complexity, data-oriented programming, how we can separate code from data in Java, and ways to represent immutable data in Java and data with records.
Overview of Object-Oriented Programming (OOP)
For Object-Oriented programming languages, everything is an object. OOP encourages developers to create complex entities and processes, encapsulation and polymorphism using objects. Although some developers might like to announce OOP as a failure, the truth is that OOP is well-suited in some cases and not so much pleasure to work with in other scenarios. But there is no denying that badly doing OOPs can be awful for the project.
Read: How to Improve Your Programming Skills
Some of how OOP can increase the system complexity are:
-
Mixing code and data can involve multiple relations between classes.
-
Creating mutable objects can make it difficult to read the code and explicit synchronization in a multi-threaded environment.
-
With mutable data, code becomes unpredictable.
-
Most OOP languages also make JSON conversions difficult.
-
Locking data in objects as members makes it hard to serialize data.
-
While using inheritance, code gets locked into classes as methods making class hierarchies complex.
Now that we know how OOP can sometimes make the development of an application complex. Let’s find out how Data Oriented Programming simplifies the system complexity.
What is Data-Oriented Programming
The core aim of data-oriented programming is to decrease system complexity by separating code from data. When the developer separates code from data, it creates two essential parts: Data entities and Class modules.
Read: Apache Beam Using Java
DOP works on four fundamental language-agnostic principles. These four principles are as follows:
Principle 1. Separating code from data in a way that code can reside in functions whose behavior does not depend on encapsulated data.
Principle 2. Use Generic Data Structures to represent Data Entities.
Principle 3. Make data immutable
Principle 4. Separating Data Schema and Data Representation.
These principles allow code reusability in different contexts, test code in isolation, make the system less complex, leverage functions for different contexts, flexible data model, uncomplicated data access, code behavior predictability, fast equality checks, concurrency safety, freedom to choose data to validate, optional fields, automatic data model visualization, and advanced data validation conditions.
Read: Best Practices for Unit Testing in Java
However, just like any other tools, paradigm, and principles, DOP principles also have cons that a developer has to overcome.
These cons of DOP principles are:
-
Codes are able to access data without any control
-
No packaging
-
More entities in the system
-
No data schema
-
No compile-time check to validate data
-
The slight performance hit
-
Explicit type casting in Java
-
Need library for persistent data structure
-
Week connection between data and schema
Separating Code From Data in Java
Suppose we want to build an online book store system that adheres to the following requirements:
-
Two user types: Sellers and Customers.
-
With email and password, the user login to the system.
-
Customers can buy books.
-
Customers and sellers can search for the book by its title or author’s name.
-
Sellers can list the books they want to sell.
-
Books can have several copies.
Read: Microservices in Java
A basic Java design for this system would contain the following classes:
-
BookStore: The central part of the system
-
Book: A book
-
BookItem: Copies of the book
-
Customer: The buyer of the book
-
Seller: The bookseller
-
User: The base class of customer and seller
-
Catalog: List of books
-
BookAuthor: The author of a book
To help you understand, we will divide the class into two parts: a coding class with static methods and a data class with members. Now following the 1st principle of Data-Oriented Programming, we can organize data entities into nested lists as
-
The Catalog Data
-
Data about books
-
Data about book items
-
Data about authors
-
Data about book sell
-
-
User Management Data
-
Data about customers
-
Data about sellers
-
Data about members
-
The best way to discover data entities is to group the system as a nested list as shown above or as mind maps.
The most precise way to visualize the Data-Oriented Programming (DOP) system’s data entities is to draw an entity relationships diagram with different arrows that represent composition or association. And as an experienced Java developer, you can design the class diagram for the system by using some design patterns.
Representing Immutable Data with Immutable Class in Java
Data-Oriented Programming in Java. Applying the second principle of DOP in Java comes to thread safety, ease of caching, no hidden side-effects, and no identity mutation. We have three different methods in Java to represent immutable data:
Read: How to Build a Web Application Using Java
-
Data records
-
Immutable classes
-
Persistent hash maps
The members of Immutable classes, on the other hand, cannot be modified and they also have no methods. Writing every immutable class requires a lot of boilerplate code due to the use of constructors, equals(), getters, toString(), and hashCode(). So we use a Java annotation such as @value to avoid using boilerplates.
Read: Desktop App for Programming Language
To help you understand, here is how we can represent the online bookstore system’s catalog data using @value annotation:
@Value
public class BookAuthorData {
String name;
List<String> bookIds;
}
@Value
public class BookData {
String title;
String ISBN;
Integer publicationYear;
List<String> bookauthorIds;
}
@Value
public class CatalogData {
String items;
Map<String, BookData> booksByIsbn;
Map<String, BookAuthorData> bookauthorByIds;
}
How to Represent Data with Records
In Java14 there is a concept of a record that offers a way to model data-only aggregates. So with records, our data model will look something like below:
public record BookAuthorData (String name,List<String> bookIds) {}
public record BookData (String title,String ISBN,Integer publicationYear,List<String> bookauthorIds) {}
public record CatalogData (String items,Map<String, BookData> booksByISBN,Map<String, BookAuthorData> bookauthorByIds) {}
Records can be created like immutable classes as:
|
Conclusion
So that was it for the blog, we hope it helped you understand the drawbacks that Object-Oriented Programming has, and how Data-Oriented Programming (DOP) can help you out in making your project less complex.
If you are a developer yourself who wants to build an application based on DOP, then you need to learn the basics and start working on it. You can not only take help from our blog but also from different books available in the market.
On the other hand, if you are a business owner who wants to invest and develop a DOP web app for your business, then hire developers from companies like Decipher Zone Technologies now!