Classes and packages encapsulation in an hexagonal architecture - java

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.

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.

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.

Related

Class library for design patterns in Java? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
I find my self writing again and again the same programming patterns in many new projects.
I have been thinking about creating my own reusable library of typical implementations of such patterns -not trying to cover all possible design patterns, but only them that experience has shown that it makes sense to put such typical implementations in a library (e.g., adapter, factory, etc ...)- but before I would like to know if there is not an existing library for this purpose already available for Java?.
I know that it is very difficult to completely generalize programming patterns in a way that they could be reused across different implementations with complex requirements (e.g., composition of patterns, classes participating in more than one pattern, etc ...). However, most of the time the pattern instantiations I need are quite simple and standard, and in many situations the implementation work could be sped up a bit with the use of such a library.
Thanks for your feedback.!
Design pattern are just... patterns. They aren't classes ready to use for anyone, but common concepts found across several projects. That's why you won't find a Design Pattern API.
This is precisely the reason why I created PerfectJPattern. Just make sure to check out and understand the code examples. They are available for download as well as in the site documentation pages for each of the Pattern implementations. If you read the GoF book, then you will understand the examples more easily.
For instance, if you want to use the Composite Pattern in your code, and if you use PerfectJPattern you only need to specify which interface (generic parameter and class instance) you would like to use as Composite and the rest is provided to you, see PerfectJPattern Composite. At the bottom of that page, a working example is provided that shows how to accomplish that.
Another aspect you should also take into account, is that in PerfectJPattern you do not necessarily need to reuse the generic Pattern implementations (e.g. perfectjpattern-core Maven submodule), you also do have the choice to only reuse the pure abstract level (perfectjpattern-api Maven submodule) and provide the implementation yourself. In PerfectJPattern you have the flexibility of reuse at different levels of abstraction since there is a fine-grained layered design reflected also in the Maven project structure. Reusing the perfectjpattern-api gives you an abstract template guideline if you wish, that will help you speed up your own Design Pattern implementations. However, ideally you should reuse as much as possible.
Update: following up on a comment below, it is worth noting that not all Patterns can be fully compotentized see From Patterns to Components. Some Patterns can be only partially componentized and some others not at all like the case of the Singleton. The Singleton depends too much on the context and that's why you can only find an interface in PerfectJPattern. However in PerfectJPattern the following Patterns are fully componentized e.g. Observer, Command, Adapter, Decorator, Composite, Proxy, Visitor, DAO, etc.
I disagree with the other answers that no reuseable implementations can be created for design patterns. However, it might not always be straightforward, and involves a lot of abstract programming.
Coming from C# I was missing the simplicity of the observer pattern in Java. (events in C#) After finishing a reusable generic observer for Java I came across the PerfectJPattern library.
It might be worthwhile to check it out.
A componentized pattern is in essence a context-independent, reusable
and type-safe variation of the original pattern that covers at least
as many use-cases as the original pattern and that does not require
developers to re-implement the same boilerplate code in every
different context. Design Patterns are reusable in terms of design,
componentized patterns are reusable in terms of design and code.
Kudos for wanting to reduce any form of duplication possible. "Don't repeat yourself" is one of the most important principles in programming.
As some extra arguments design patterns can be centralized in a library I give you some further examples:
Lazy initialization in C#.
Entire LINQ is based on IEnumerable.
Java's attempt at a reusable Observer pattern. (I didn't say all are good.)
Several patterns integrated in the Spring framework.
As in Pangea's answer: Java JT framework.
What you are looking for is PerfectJPattern.
Checkout dp4j. It allows you to implement the Singleton pattern with #Singleton and lazy initialize it with #Singleton(lazy=true). It is a "collection of reusable componentized Design Patterns implemented in Java".
For the Singleton recommend dp4j. To implement a Singleton you annotate your class with #Singleton and to lazy initialize it you annotate with #Singleton(lazy=true).
If you find yourself repeating similar code in multiple projects, it might be a good idea to extract the portions that are repeated into a library of reusable code in hopes of avoiding repeating yourself in the future.
This is unlikely to lead to fully general reusable implementations of design patterns.
JT Design Pattern Framework for Java/j2EE
A lot of the patterns are built into the Java SE - you may not notice.
Decorator is all over the java.io package.
The java.sql package is AbstractFactory.
All the wrapper classes are Flyweights.
I stand with those who say don't look for a pattern library. They should be discovered as you write your code.
It is possible in a languange which offers higher order functions and some other stuff. Here are some slides which references a paper which discusses 'the origami pattern' library. It shows 'library code' for the following patterns: Composite, Iterator, Visitor, Builder. So if you want to try that out on the jvm you can today, just use scala. http://www.slideshare.net/remeniuk/algebraic-data-types-and-origami-patterns
Do you see a forest or trees?
Design patterns should become apparent rather than be selected up front. By the time they become apparent, you don't need the pattern because the code exists. Then you marvel at how the solution solved itself and your brain subconciously selected the right approach. It gives you that warm fuzzy "i trust that code" feeling.
If you build a design pattern library, you have built yourself a big hammer (or hammer factory, or hammer factory factory [1]) and everything becomes a convenient nail (including screws) resulting in lots of sore thumbs and bowls of spaghetti in your development team.
[1] http://discuss.joelonsoftware.com/default.asp?joel.3.219431.12

Hierarchy of utility classes behind a facade?

What practices exist when it comes to organizing utility classes where some could be subset of others?
As an example, you could have a FileUtil class with methods related to Files and a subset of this class for checking File formats.
A Facade pattern is generally used more as a convenience/organizational construct rather than a hierarchical way of structuring unrelated methods. That is, when you've got several classes which appear to be used in the same manner throughout your code, you make a facade. It's purpose is to support the idiom that you don't repeat yourself (D-R-Y.)
If you've got a bunch of utility classes for various things, I'd keep them as separated as possible. If you've got a few methods which are used together in an identical manner repeated ad nauseum throughout your code, then I'd think about grouping them together in some higher "master" utility. Without seeing or looking at your code this is about the best advice I can give.

how to organize interfaces and classes

I know this question has been asked and answered many times, but I am still asking the same question again...
I have started working on a travelling application and for which currently I am working on creating on the creation of the underlying DAO so I am planning to create a generic DAO, its implementation and again an interface for each entity class.
My query is what is the best way to organise all these interfaces as well as their Implementation.
Thanks in advance
If I understand the question correctly your looking for suggestions on organising your packages?
I'd split then between. com.yyy.zzzz.dao.interfaces and com.yyy.zzzz.dao.impl
You're the only one who can take decisions on how your application should be organized. You can, of course, follow some recommandations such as the Java Naming Convention for packages, or even try to split your packages for each tier implied in your application; but in the end, you have to choose for yourself.
#Kevin D's solution is correct, you could use the com.company.project.dao.interfaces (I wouldn't use interfaces as it's a plural and I avoid plural in package names, but again it depends on you) and com.company.project.dao.impl or you could use packages to split different implementations. It's as you want. And no one should tell you how to split your own application (except your team).
The only (but still facultative) rule I would tell you to follow is "Have coherent names".
That means choose your project convention, but stick to it, and of course the names you choose for your packages (but it also applies on classes, variables) must represent their content (but I suppose this is common sense).
On another note, I don't know the context of your work, but you should really read Adam bien's Weblog, you'll see some articles on best practices regarding DAO and "default implementation", maybe it will concern your project.
Resources :
DAO's aren't dead - but they either collapsed or disappeared
Service s = new ServiceImpl() - Why are you doing that ? (not really related to DAO but still your "default implementation" made me think of this)
JPA/EJB3 killed the DAO

OK to put my public interfaces into their own package

Would it be OK to put my public interfaces into their own package (for my organisation only).
for example
com.example.myprogram - contains all normal code
com.example.myprogram.public - contains public accessible interfaces
com.example.myprogram.abstract - contains abstract classes
Is this a good or a bad thing to do, are there any disadvantages?
I wouldn't like this practice at all. You should group classes, both abstract and concrete, and interfaces according to functionality.
Look at the Java API as an example. Did Sun separate the Collections interfaces from implementations? No. Sun's practices aren't always the best guide, but in this case I agree.
Don't do it.
I can suggest you 2 common ways:
If you really think that your interfaces can have more implementations in future (i.e. you're working on API) then move them to a separate module and create there special package with name 'core', for example. (com.example.myprogram.core). Implementations should be in correspondent packages (like com.example.myprogram.firstimpl).
If you have only 1 implementation then let all your interfaces be in com.example.myprogram package and all concrete classes in com.example.myprogram.impl package.
I can't see that as being bad practice, however you might wanna consider as an alternative organizing your stuff per logical functionality rather than syntactic definition, so that all code for a given unit of functionality interfaces/abstract classes/normal code goes in the same package. This is one of the principles of modular programming.
Said so, putting all the interfaces (but only those) in a separated package might be necessary depending on the size of the project, and might eve become almost necessary if you have a pure component based plugin architecture (so that other module know only about interfaces and the actual implementation is somehow dynamically injected).
Public interfaces are a formal contract between system modules or systems. Because of that, it makes sense to isolate them from the remainder of the code, to make them stand out.
For example, in a system I've worked on, all public interfaces between the server and client components of the system have been placed in a special system module (called, no surprise, "api"). This has a number of desirable effects, among which these:
- semantically, you know where to look if you need any kind of information on how communication should take place
- you can version the api module separately, which is especially useful when you don't want a moving target, i.e. you sign a contract to deliver an application which will support "the api v.1.1" rather than constantly playing catch while someone else changes the interface and requires you to adapt your side
That doesn't mean you shouldn't organize them further in sub-packages to distinguish what they are for. :)
In summary, you are doing the right thing by separating the interfaces from the rest of the code base, although depending on your specific needs, you might do well to take it a step further and isolate the interfaces in a separate system module.

How to organize packages (and prevent dependency cycles)?

I've been running some metrics on my Java project and apparently there are a lot of dependency cycles between packages. I didn't really know how to organize stuff into packages, so I just did what made sense to me, which is apparently wrong.
My project is a neural network framework. Neural networks have Neurons, which are connected to each other with Connections. They need to depend on each other. However, there are also different types of Neurons, so I thought it'd be a good idea to put them all in there own 'neurons' package. Obviously a Connection isn't a Neuron so it shouldn't be in the package, but since they refer to each other, I now have a circular dependency.
This is just an example, but I have more situations like this. How do you handle these kinds of situations?
Also, I read that classes in a package higher up in the package hierarchy are not supposed to refer to classes in packages that are deeper. This would mean that a NeuralNetwork class in package 'nn' can not refer to the Neuron in package 'nn.neurons'. Do you guys follow this principle? And what if I would move NeuralNetwork to 'nn.networks' or something? In that case, it would refer to a sibling package instead of a child. Is that better practice?
The antcontrib VerifyDesign task will help you do what you want:
For example, if there are three
packages in one source tree
* biz.xsoftware.presentation
* biz.xsoftware.business
* biz.xsoftware.dataaccess
and naturally presentation should only
depend on business package, and
business should depend on dataaccess.
If you define your design this way and
it is violated the build will fail
when the verifydesign ant task is
called. For example, if I created a
class in biz.xsoftware.presentation
and that class depended on a class in
biz.xsoftware.dataaccess, the build
would fail. This ensures the design
actually follows what is documented(to
some degree at least). This is
especially nice with automated builds
So once you have decided how things should be organized you can enforce the requirements at compile time. You also get fine-granied control so you can allow certain cases to break these "rules". So you can allow some cycles.
Depending on how you want to do things, you might find that "utils" package makes sense.
For the particular case that you cite... I might do something like this:
package nn contains Nueron and Connection
package nn.neurons contains the subclasses of Nueron
Neuron and Connection are both high-level concepts used in the NeuralNetowrk, so putting them all together makes sense. The Neuron and Connection classes can refer to each other while the Connection class has no need to know about the Neuron subclasses.
First of all, you are rightfully concerned because circular dependencies between packages are bad. Problems that come out of it grow in importance with the size of the project, but no reason to tackle this situation on time.
You should organize your classes by placing classes that you reuse together in the same package. So, if you have for example AbstractNeuron and AbstractConnection, you’d place them in the same package. If you now have implementations HumanNeuron and HumanConnection, you’d place these in the same package (called for example *.network.human). Or, you might have only one type of connection, for example BaseConnection and many different Neurons. The principle stays the same. You place BaseConnection together with BaseNeuron. HumanNeuron in its own package together with HumanSignal etc. VirtualNeuron together with VirtualSignal etc.
You say: “Obviously a Connection isn't a Neuron so it shouldn't be in the package..”. This is not that obvious, nor correct to be exact.
You say you placed all your neurons in the same package. Neither this is correct, unless you reuse all your implementations together. Again, take a look at scheme I described above. Either your project is so small you place all in the single package, or you start organizing packages as described.
For more details take a look at The Common Reuse Principle:
THE CLASSES IN A PACKAGE ARE REUSED TOGETHER. IF YOU
REUSE ONE OF THE CLASSES IN A PACKAGE, YOU REUSE THEM
ALL.
How do you handle these kinds of situations?
Circular dependencies aren't inherently bad. In fact, this can sometimes be a case of the "cure being worse than the disease": extracting an interface increases the level of complexity of your code and adds another layer of indirection. That's probably not worth it for very simple relationships.
I do not think cyclic dependencies like the ones you describe have to be bad. As long as the concepts that are interdependent are at the same level of abstraction and relate to the same parts of the architecture, it may not be necessary to hide these from each other. Neurons and Connections fit this bill in my understanding.
A common to reduce such couplings is to extract interfaces, and possibly even put these in a separate module. Simply organizing by packages inside a single project does not allow you to hide implementation details sufficiently. A common pattern that allows you to really hide implementations is as follows:
Client Code ----> Interfaces <--- Implementation
In this pattern, you hide the "Implementation" module from the client code, which means the code in the "Client code" module doesn't even see the implementation code.
The nesting of packages serves several purposes: Some projects may have a domain model which is organized in packages. In this case the packages reflect some grouping of the domain, and references may go up/down packages. When it comes to things like implementation of services, your suggested pattern is quite common and a good thing to follow. The deeper in the package hierarchy you get the more specific the class is believed to be.
What kind of code size are we talking about? If you only have 10-20 classes, you probably don't need to (and shouldn't) over-organize your code into packages just for the sake of it.
As your project grows, the first distinction you want to make is to separate user-interface code from the underlying data model and the logic. Having cleanly separated layers is crucial in order to be able to do proper unit testing.
If you're having trouble in getting rid of the circular dependencies, it is probably the case the the classes are actually interdependent, and should reside in the same package.
Getting the abstraction layers right is probably one of the most important aspects when designing the overall code structure.

Categories