3

I would like to know if in Java (JDK 17) there is a way to easily handle classes and packages encapsulation in an hexagonal architure. I would like to make unavailable classes present in an adapter to the domain. To illustrate my goal, say we have this package organisation:

com.company
           |-domain
                  |-model
                        |-Customer.java
                        |-Product.java
                  |-ports
                        |-DbPort.java
                        |-ServiceBusPort.java
                  |-services
                           |-CustomerService.java
                           |-ProductService.java
           |-adapters 
                   |-inbound
                           |-rest
                               |-CustomerRestAdapter.java
                               |-ProductRestAdapter.java
                           |-bus
                               |-ServiceBusAdapter.java
                               |-RabbitAdapter.java
                   |-outbound
                           |-db
                              |-entities
                                      |-Customer.java
                                      |-Product.java
                              |-repositories
                                      |-CustomerRepository.java
                                      |-ProductRepository.java
                              |-mappers
                           |-bus
                               |-dtos
                                   |-CutomerDto.java
                                   |-ProductDto.java
                               |-mappers

What I want to achieve is: all classes and packages under com.company.adapters should not be visible from the com.company.domain package. The goal is to prevent developers to use for example the class com.company.adapters.outbound.db.entities.Customer in com.company.domain.services.CustomerService. But classes inside com.company.domain should be accessible from everywhere.

Rémi Bantos
  • 1,899
  • 14
  • 27
akuma8
  • 4,160
  • 5
  • 46
  • 82

2 Answers2

1

To achieve strong encapsulation with Java, you could make use of maven modules per layer, left, right and domain. I have not tried but I guess Java 9 modules would also help here. Check this link.

Another approach I use for the sake of simplicity and code readability, is to use a single module, without strong encapsulation, but different packages per layers, one for domain, another for infra..

And, to enforce architecture rules within this module, like hexagonal ones, I usually define a unit test which fails in case of any violation, for example when some domain package code directly depends on a technical API client implem defined outside the domain. So far I have used Archunit framework for that.

Also I prefer this approach because, as a developer or new joiner for example, IMO it is much easier to break some architecture rules / encapsulation patterns, not being aware till the code review, rather than breaking / ignoring a test which would fail the build, and which would also act as a spec for these rules.

Rémi Bantos
  • 1,899
  • 14
  • 27
  • Thanks, I didn't know ArchUnit and I think that could help a lot if it works. My first idea was to divide the application into multiple maven modules but I would like to keep things simple. Thank you – akuma8 Aug 23 '22 at 13:50
0

What you want to achieve is definitey doable in Java.

There are numerous examples - for example check out the JAXP library:

While you use the DocumentBuilderFactory to instantiate a DocumentBuilder and ultimately parse a Document, everything but the factory are interfaces abstracting away a concise implementation, which is the pattern you are aiming at.

To get more concise: All that you need to do is come up with the right combination of classes, interfaces and packages. Have a look at Design Patterns which describe what you need to do. The book "Design Patterns" by the Gang of Four is very helpful in that respect.

Queeg
  • 7,748
  • 1
  • 16
  • 42
  • Thanks but I don't see how your answer could solve my issue. – akuma8 Aug 02 '22 at 09:19
  • Grant. You need something that directs you towards decisions and tasks. I refined my answer. – Queeg Aug 02 '22 at 09:34
  • It’s not related to the design, I want a physical solution to reduce the scope of classes. I am looking at using modules introduced in Java 9. – akuma8 Aug 06 '22 at 09:29
  • If you have bad design, how are packages and modules going to help? – Queeg Aug 06 '22 at 14:34
  • How hexagonal architecture is a bad design? I found this article which could help: https://medium.com/swlh/a-practical-example-of-applying-java-modules-in-a-hexagonal-architecture-d345deec654b – akuma8 Aug 06 '22 at 15:24
  • It seems I underestimated the hexagonal architecture. You are done with that part. So have fun with modules now. :-) – Queeg Aug 06 '22 at 15:40