Sometimes when we have āwhat package does this go in?!?!ā style problems, the best course of action can be to defer the decision. Often if you havenāt even implemented it yet then you arenāt really sure what will be similar or different, how painful it will be to use if you split different things out.
Implement it all in one package but keeping in mind to use good compartmentalization. Donāt make an āinterfaceā unless itās going to have multiple implementations, etcā¦ Donāt assume two things are going to be different implementations of the same interface just because āthey do similar but different thingsā. Make methods do what they say and say what they do. (For example, if getListOfFoo() is really getListOfFooAndUpdateCounts() or whatever then probably there is an API problem). And so onā¦ basically just good design choices. Think about testability if you wanted to write unit tests. (Can you mock things to test real units, etc.)
And as you get things working, likely those choices will change anyway. When itās all working from front to back, you can then start to apply organizational and package ideas to it and move them around.
At that point a different set of questions is important:
is every user of interface X going to need implementation Y? (factors into .jar separation concerns)
is every user of thing X going to always need to import these three packages? (factors into package splitting)
if I replace implementation Y with implementation Z am I going to have to surgically remove 50 classes one at a time or can I just delete this directory?
ā¦sometimes the answers to those questions will even compete with one another.
And there are personal philosophies and conventions involved in that as much as anything else. Iāve waffled on this a few times even within my own designs.