How to organize packages (and prevent dependency cycles)? - java

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.

Related

Classes and packages encapsulation in an hexagonal architecture

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.

What is the purpose of java packages having unique names?

Whenever I am watching a Java tutorial, they always start their package names with com or org, something to do with the domain of the developer. However, I do not get the overall purpose of doing this, because I don't understand how having a unique package name affects anything. Why not just name it whatever and not worry about if someone else has named their package the same as yours? Why does it matter?
What is the purpose of java packages having unique names?
The purpose is to avoid accidental naming collisions between different codebases, and the problems this causes; see below.
Why not just name [a package] whatever and not worry about if someone else has named their package the same as yours? Why does it matter?
That's what a lot of people do. They ignore the issue.
However, suppose you (or someone else) needed to combine two codebases with poorly or unfortunately chosen package names that resulted in a package name collision.
New classes would appear in packages where they were not anticipated by the original authors.
New implicit imports would appear, possibly leading to compilation errors or unintended changes in meaning. (E.g. suppose that one codebase defines its own Class class.)
There could be collisions of fully qualified class names. In such cases, one class would "hide" the other.
Code that uses reflection based on package names to find components could break.
Classloader resource location could break because of unexpected resources appearing or because of hiding.
At the very least the carefully crafted organization of packages and subpackages would be messed up. For example, classes would show up in the javadocs in packages that don't make as much sense as they used to.
To deal with this, you / they would have to re-engineer the code to avoid the worst effects of the package name collisions. Admittedly, a modern IDE's refactoring support could do most of the work ... if you do things in the right order. But not all of it; e.g. reflection, resources and references in javadocs.
And then you have the problem of maintaining a codebase that has diverged radically from the original version of at least one of its components. Tools like git changeset merging most likely won't cope anymore ... assuming that you fixed the problem by changing package names. You would have to apply any changes from "upstream" by hand, or not track them at all.
To my mind, the last is probably the most troubling consequence of a collision.
Since there is an easy way to avoid / minimize the risk ahead of time, it makes sense to do it.
(It is like putting on the seatbelt in a car ...)
Because if they all had the same name there would only be one package, not 'packages'.

How to split a Java library source into two blocks, keeping one package?

We are creating an android library for use with Android. That means an Eclipse-like IDE and an Ant-like build process.
The nature of the library is that it has two distinct parts, representing different levels of abstraction - let's say 'upper' and 'lower'.
Assume, for the purposes of this question, that we need to call methods in one part from the other, but would like to keep those methods hidden from the library user. I've scoured the usual references but they all stop at the point of explaining package name conventions and scope rules. I've failed to find anything that answers this on SO, though this was useful.
The immediate solution is to simply have everything in one package and for those methods to be package-private. However, for reasons of maintainability, clarity, and not-having-100-files-in-one-folder we'd prefer to split the parts into different folders.
The obvious splitting point is to split the (let's say 'wibble') package into com.me.wibble.upper and com.me.wibble.lower packages/folders, but that makes any interconnecting methods undesirably public. In mitigation they could be hidden from the javadoc with #hide.
Another thought is whether could we split the parts at the top level and instead of the classic /main and /test folders have /upper, /lower and /test and all parts share the same com.me.wibble namespace. I'm unsure if/how Eclipse would cope with that.
Is there a conventional way of doing this, or is it just not done? If there are ways, what are the pro's and con's?
hmmm......Instead of asking for the solution, sometimes it is better to give the question. WHY you want library users to have a restricted view may generate a better answer than the HOWTO. There are a few answers I thought of but didn't give because I don't know the motivation behind the question (I don't want to waste your time with an answer that is not applicable).
/upper,/lower/,/test doesn't make your situation any nicer. It just makes the project more organized. Whether they are all in the same folder or separate it doesn't affect much.
It sounds like you need public 'interfaces' for library users while having private 'interfaces' for your own use. This is possible with hacking but can be painful if this is large pre-existing collection of code.

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.

Categories