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
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
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

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • How To Approach Dependency Management in Java [Video]
  • How To Convert Image Files Into GIF or WebP Format Using Java
  • How To Validate Names Using Java
  • How to Convert a PDF to Text (TXT) Using Java

Trending

  • MCP Servers: The Technical Debt That Is Coming
  • System Coexistence: Bridging Legacy and Modern Architecture
  • Optimizing Integration Workflows With Spark Structured Streaming and Cloud Services
  • Unlocking Data with Language: Real-World Applications of Text-to-SQL Interfaces
  1. DZone
  2. Coding
  3. Java
  4. Reusable Components in Java

Reusable Components in Java

A guide to component based design and development of Java coding to follow SOLID patterns and practices for optimal Java development.

By 
Grzegorz Ziemoński user avatar
Grzegorz Ziemoński
·
Nov. 04, 16 · Opinion
Likes (23)
Comment
Save
Tweet
Share
26.5K Views

Join the DZone community and get the full member experience.

Join For Free

I can't name exact sources, but I feel like ever since I started learning how to program, I was reading tales and legends about "reusable" components, modules and so on. It was not until recently, that something clicked in my head and I found this concept pretty basic. In this text, I'll try to shed some light on creating components and making them reusable. Obviously, it won't be any close to complete, rather an inspiration to explore further.

What Is a Component?

You can find a lot of definitions and approaches to defining a component. For the sake of this article, I'll define it like this:

Component is a class or bunch of classes with cohesive responsibilities that form a larger whole.

Now, for some of you, this will be valid, whereas some may say that I'm actually defining a module, and some of you might want to nitpick other details in the definition. For the second group, my excuse is that the difference between a component and a module is very blurry (try Googling it; everyone seems to have their own understanding). For others, the comment section awaits!

What Goes Inside a Component?

Let's focus on the middle part of my definition — cohesive responsibilities. I'd describe this as the likelihood of changes happening to two classes together along with their conceptual cohesion. To provide a quick example, we can imagine that the Customer and MailSender classes won't have too much in common in a typical project, so they won't be in the same component. Mail and MailSender on the other hand seem to complement each other — every new piece of information Mail class will hold, MailSender will have to reflect in the actual email sent. Therefore Mail and MailSender are good candidates to be in the same component.

Does that mean imaginary MailController and MailRepository will end up in the "mail component," too? There are consequences, so it depends. In my recent project, I decided to keep controllers inside components and so far I haven't experienced any issues. There's a great text by Simon Brown that gives some insight into his understanding of Layers, hexagons, features, and components. I definitely recommend reading this one, before you make up your mind for good. I also recommend you experiment on your own, because projects vary and so do the best solutions.

Creating a Component

Having identified two classes that are more cohesive to each other than to the rest, we should put them together — we want component structure to be explicit, not hidden in the forest of other things, not imaginary in the mind of an architect. We have multiple means of doing that - packaging, Maven modules, Java 9 modules, OSGi, etc. In most projects, this implies that we should seek packaging (or "modularization") by functionality, rather than by object type (see also: Package Structure).

Encapsulating a Component

Oh, I could write some cool stuff about component encapsulation, but it so happens that I already did. Make sure to check out Java Encapsulation for Adults, if you haven't already. TLDR; Use expressive packaging and/or visibility modifiers and interfaces to encapsulate your component's internals (and save your ass at the dance party).

Reusing a Component

To reuse a component, we just include it in our project (if necessary) and use its public API. It's so simple and yet we rarely hear about great systems built from reusable components. More often we hear about the dreaded "BIG BALL OF MUD." Why?

I believe it's not (yet) mathematically proven, but a component's reusability is inversely proportional to the amount of magic it uses and dependencies it requires. Since poor dependency management and magic seem to be ubiquitous in software, reusability tends to suffer. We'll work through this theorem using an example. Let's take a look at the git component from my blogging platform project.

I claim that this component keeps track of a configured Git repository by exposing an endpoint to notify it about changes and allows its clients to read from the repository. What can we say about this component's reusability?

Firstly, it's reusable inside this project, as long as we need to keep track of only one repository. If there were more repositories to track, we would need to change both service's and component's implementation.

Secondly, it might be reusable in other projects using Spring, but we would have to do a few things:

  • Deploy it as an artifact.
  • Bundle it with the ExceptionUtils class that it's using, which might involve copying the class or setting a dependency on utils artifact.
  • Make sure the other application is using a compatible version of Spring — example of how a dependency can lower reusability.

Thirdly, it might be reusable in other projects that are not using Spring, but we would have to:

  • Deploy it with the necessary dependencies (same as the first two criteria above).
  • Remove the Spring dependency (remove the controller, remove Spring's annotations from the service, expose lifecycle methods through component's interface) — example of how unwanted dependency and magic lifecycle can lower reusability.

Lastly, in this example, the only in-project dependency is a utility class, which is fine. Imagine what would happen if this component had a dependency on a more project-specific class e.g. Post. Anybody who'd like to use this component would have to declare a dependency on blogging-specifc stuff or reimplement non-configuration logic in the blogging platform. Therefore, watch for project-specific dependencies in technical components like this example one!

Enough. I think that two things should be really clear about the example component:

  • The current implementation is not very reusable.
  • It has a lot of potential for reusability improvements.

So..

HAHAHAHAHA! GRZEGORZ, YOU FAILED! TIDY JAVA? BS! NON-REUSABLE JAVA! GO AND REWRITE, HAHAHA!

No, no, no. YAGNI boy, I'd rather KISS a component than make it maximally reusable "just in case." Look at how much complexity could changes mentioned above introduce. You don't want that complexity, until absolutely necessary. Therefore, the key takeaway of this part should be:

Keep your components potentially reusable, so that's it's possible to reuse a component either directly or with a small change. Don't shape your code around unnecessary reusability.

Summary

By defining a component as a class or bunch of classes with cohesive responsibilities, we can move the term from the world of tales and legends to reality. We grab conceptually cohesive classes that might change for the same reasons and put them together into a package, module or whatever else we're using. A component should be well encapsulated to encourage loose coupling. Component's reusability is inversely proportional to the amount of magic it uses and dependencies it requires. We should acknowledge this truth, but not use it as a reason to actively fight every reusability flaw until we really need it — good software design rules still apply. Happy applying!

Java (programming language) Dependency Reusability

Published at DZone with permission of Grzegorz Ziemoński, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • How To Approach Dependency Management in Java [Video]
  • How To Convert Image Files Into GIF or WebP Format Using Java
  • How To Validate Names Using Java
  • How to Convert a PDF to Text (TXT) Using Java

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • 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:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!