DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • Auditing Spring Boot Using JPA, Hibernate, and Spring Data JPA
  • Unraveling Lombok's Code Design Pitfalls: Exploring Encapsulation Issues
  • 10 Essential Programming Concepts Every Developer Should Master
  • Architecture and Code Design, Pt. 2: Polyglot Persistence Insights To Use Today and in the Upcoming Years

Trending

  • Unraveling Lombok's Code Design Pitfalls: Exploring Encapsulation Issues
  • What Is Good Database Design?
  • Selecting the Right Automated Tests
  • GenAI-Infused ChatGPT: A Guide To Effective Prompt Engineering
  1. DZone
  2. Data Engineering
  3. Data
  4. Java Records: Making Bad Designs More Convenient

Java Records: Making Bad Designs More Convenient

While "records" seem to be universally welcome, developers, especially fans of the object-oriented paradigm, should be careful when considering this new feature.

Robert Brautigam user avatar by
Robert Brautigam
·
Sep. 24, 19 · Analysis
Like (7)
Save
Tweet
Share
15.49K Views

Join the DZone community and get the full member experience.

Join For Free

Java records
Learn more about Java records, and how easy it is to make the wrong decisions. 

There is an official JEP 359: Records (preview) that proposes to introduce "Records", i.e. pure data structures into Java. With it, Java continues to follow other contemporary languages into the territory of "multi-paradigm" programming.

This article explores what this change means for object-orientation, Java development, and our industry in general.

Old Name, Old Feature

First of all, "records" are not new nor modern — quite the opposite actually. Records and structures have been around forever in programming; they were present in COBOL in the 60s, and then later in widely used languages such as Pascal, C, and others.

These languages followed the procedural programming paradigm, which meant that data was modeled as plain data, and then there were procedures where the "business-logic" was implemented by manipulating the data that was either passed as a parameter, available globally or from somewhere else.


Then object-orientation and Smalltalk came along in the 70s and 80s and did away with pure data structures in favor of objects, which were thought of as independent agents cooperating and communicating with messages to implement the requested logic. Even in the 90s when Java was created, this original idea still persisted strongly enough that Java originally did not introduce pure data structures.

Then, our industry virtually exploded in the late 90s; "e-business" was now a thing. Java introduced the "Enterprise Edition," and there was a huge demand for Java/JavaEE developers. This is where cracks started to appear on the transition to object-orientation. There were not enough object-oriented developers, so most people (including myself admittedly) came from a procedural background. At the team where I was a junior developer, nobody explained how object-orientation was supposed to work, so we basically continued to produce C code in Java. Instead of data structures, we used "Beans," and instead of procedures, we used methods that were awkwardly grouped into random classes, usually called Managers. Most projects at the time operated this way.

In the 20 years since then, this basic design did not change much. Layered architectures were already a thing in the 90s, still a thing today. Having a data model (sometimes called "domain model" these days) separately from the logic is still the dominant approach for Java software development by far.

So with this in mind, it seems pretty clear that introducing records is not a step forward at all, rather it is literally a step back towards our procedural past. Were things in the past better, was the procedural approach successful?

The State of Our Industry


To complete our historical perspective, it might be beneficial to look at where we are now in more detail. I will not be able to summarize that more succinctly than this.

Just to stay in the "enterprise" sphere, there is an adversarial relationship between the business and development. Not between people mind you, but between the areas. Development is usually not part of the business at all, they are a "service" the business reluctantly keeps around or even outsources. Development and IT, in general, is a "cost center". That is MBA talk for a thing that just costs money but is not considered useful.

This wasn't always like this. Even as late as the 90s, business people were excited to work with us, to tell us how they operated, and asked us to help them come up with new ideas for customers. We worked side by side with them not just developing software, but as a part of business operations. People trusted us because we were there the whole time, saw what was happening with them, and how they worked. We came up with small enhancements almost weekly. We were also not budgeted separately, but with the business group, we were working in. We helped generate money so to speak, instead of just burning it.

So what changed? Well, many things, but most importantly, we were not good enough at our jobs. Things took too long to build, they were not working as expected, and as codebases grew, things got only worse. Then the business started pushing us away and demanded to have some form of contractual security, which resulted in less trust and communication, and so the spiral continued downward.

Despite these changes, we, as an industry, continued to do things the same way. We still think the same way and we still mostly use the same, essentially procedural approach for software design with some minor cosmetic changes. So even though Java did try to make the step forward towards object-orientation, it seems it now acknowledges that it was largely unsuccessful and it officially reverts back to the more popular procedural approach, that from a historical perspective, we already know doesn't really work well. So why would Java do this?

Motivation and Goals

The main reason given in the proposal to have records is for "modeling data as data," which would look like this:

record Point(int x, int y) {
}


Let's look at this approach pragmatically. How readable and maintainable will this code become? Let's ask some questions:

  • What does the application do with it?
  • Can I change the int to long?
  • Can I change the Cartesian coordinate system to polar coordinates?
  • Would polar coordinates be more optimal representation?
  • If I would extend this Point to 3D with a z coordinate, what would I have to change?

These are just some of the things we might be interested in when we look at Point. If you use such a construct in an application, you'll have to search the code for usages, often following through multiple layers and even through other objects where the data is simply copied out to be used somewhere completely unrelated.

So instead of that, how about this:

public final class Point {
   private final int x;
   private final int y;

   public Point(int x, int y) {
      this.x = x;
      this.y = y;
   }

   public Line connect(Point other) {
      ...
   }

   public Line throughAt(double angle) {
      ...
   }

   public Circle circle(int radius) {
      ...
   }
}


This is obviously more code, but also much more information. We know what the Point is for and how it is used. We see that the internal representation stays internal, so there is no way the application uses the Point in some other way not defined here. We can also change this internal representation freely, look at whether polar coordinates would be better in light of the logic present here, etc. And we don't have to look elsewhere to figure all this out.

So which is more "readable"? Which communicates more information? Which is more maintainable? Which is guaranteed to be used correctly? Which can be abused less?

The reality is of course that the proposed "records" are only more readable compared to conventional data-only "objects" in Java, but the proposal completely ignores that the approach itself could be wrong from a historical, maintainability, readability and design perspective.

Functional Programming


There are some arguments suggesting that records are not just read-only "structs" from C, but actually "algebraic data types" from functional programming. And because the words "algebraic" and "functional" sound cool, it must be good.

Functional programming, at its core, is the idea that software should be a composition of pure mathematical functions. Functions that receive some values (i.e. immutable data) and produce always the same value for the same parameters. Java doesn't even have a concept of immutable data nor pure functions, nor proper tools for function composition. Even the proposed records are only shallowly immutable, meaning they can refer to other objects that are mutable.

Even ignoring all that, actual real-life designs in Java are clearly not functional, but mostly procedural. It is therefore pretty clear that records will be used to support current designs, regardless what its purpose was supposed to be.

You Don't Have to Use It

This argument has to be addressed because this is a frequent response to critique on a new feature: Well, you don't have to use it if you don't want to.

This, of course, completely ignores that none of us work in isolation. We work with colleagues, external partners, consultants, or even people we have never even met. Anything the language supports will be used and everybody will have to deal with it.

Also, features of a language suggest usage, an idiomatic way certain solutions are designed and used. To suggest that a language feature can be ignored is, therefore, unrealistic.

Summary

The coming Java "record" feature is not new at all; it is, in fact, an official regression into procedural programming. That is the paradigm from the 60s that is partially responsible for the "fall from grace" of software development in the 90s and 2000s. It is a signal that the transition to object-orientation, the paradigm that had the potential to fix the issues of the procedural world, that Java began in the 90s is basically abandoned.

The notion that records are part of the functional paradigm is a red herring. Java is not, and never was, functional, and real-life Java code is pretty much procedural if anything.

So, while "records" seem to be universally welcomed, people, especially developers committed to the object-oriented paradigm, should be extra careful when considering this new feature, or even refrain from using it completely.

Further Reading

Java's Future-Looking Projects

Java (programming language) Record (computer science) Design Software development Data (computing)

Published at DZone with permission of Robert Brautigam. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Auditing Spring Boot Using JPA, Hibernate, and Spring Data JPA
  • Unraveling Lombok's Code Design Pitfalls: Exploring Encapsulation Issues
  • 10 Essential Programming Concepts Every Developer Should Master
  • Architecture and Code Design, Pt. 2: Polyglot Persistence Insights To Use Today and in the Upcoming Years

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: