We have a project that has several war files that reference one-another. I've recently realized that there is a circular-dependency between two, in particular, the utils and the models. Other services use both of these, and the utils was created for operations that would be performed on the models by other services. I was just curious what is best-practice here. Utils and models sound like they are companions to the main project, but I've never heard of a war file being called 'utils and models'... just seems strange.
Additional Info (not necessarily needed to answer the question):
To be more specific, the model uses the utils for it's type adapters, which allows MyBatis to convert timestamps to joda time. The utils uses the models, which I think is more acceptable, to do common operations on model objects.
Should I just combine both into the models war? What are some other options I would have. If I should combine them, is there some sort of design pattern that combines utilities and models together? What's the appropriate naming convention for a service that supplies both model and utility classes?
There are a lots of post on how you can remove cyclic dependencies like maven cyclic dependencies
But regarding utils a general advice is that utilities can be of two types in the sense that they are general or project specific i.e. if you are writing general utilities then those should not depend on any of your modules(they just perform general tasks) so should always come first in your reactor build order.
Secondly, for project specific utilities you can always do 'xxx.modals.utils' as in your scenario and these can easily consume your beans.
One more reason that general utilities(independent of your beans) should be kept in a different module is that they can be easily reused in other projects too. Hence you don't have to reinvent the wheel time and again!
I believe that the solution to your question would based on the view and experience and not a technical problem as such. I would suggest the following:
Go with Utils in same module if : Your Model classes' are not going to be reusable in other modules. In other words, if your Util classes is in relationship with Model classes only. It wouldn't make sense to split it as a module if your util classes are just designed for the specific model classes only.
Go with Utils in different module if : Your util classes are going to be generic. For example, your Utils classes are designed to convert the Model/Entity to Business Objects using some DataMapper like Dojo/Orika etc. That's coz, these util classes would not be tightly coupled to the Model classes as they would have the implementation to convert any type of Model to Business/Value Objects and vise versa.
This is actually been addressed by micro-services where you concentrate on loosely coupling the services which can survive independent of each other(like a plugin component).
As projects that I'm working on grow larger and larger, I'm starting to be pretty unsure about dividing classes into packages. Suppose the project has a lot of layers and in these layers are interfaces and implementation and even more sublayers (components). I always end up with a lot of packages which starts to be little confusing.
So I want to know other people's approaches to working with packages. Do you prefer to have a lot of packages with few classes or few packages with a lot of classes? Do you prefer to separate implementations from interfaces? And so on... In general your daily habits of using packages and pros/cons of your approach.
Thank you for your posts.
Packages are meant to help you find things.
If they make it more confusing than it is, you're not doing something quite right. If the package structure isn't intuitive, it can actually be harder to find classes than in a flat structure.
There are two basic schools of organising classes into packages as far as I know:
Organising by module first. Here your higher level packages are different modules of the system and you might split it further by function.
Organising by function. Here you organise by function first (e.g. all controller classes in one package, all your data containers in another and so on) and optionally subdivide it by module.
There are pros and cons for both systems, I find them roughlty equal, although I prefer the module approach slightly.
The really important thing is though to follow one system and don't mix it with the other. Don't shoehorn classes into packages they don't belong to and don't be afraid to create a new package if your new class doesn't seem to belong to any of your existing ones.
If a package seems to have grown too large, you might want to split it. But the decision of whether a package should be split or not should be made on whether there is a clear conceptual divide between classes therein and not on numbers. A package with a single class is just as good as a package with thirty classes if it's obvious why they're there.
As for separating interfaces and implementations, first off, I'd probably question the need for them. Ever so often I come across interfaces with only one reasonable implementation, which makes me question their reason to exist. (Sometimes there is a good reason, but often there isn't.)
But if you have multiple implementations for a given interface, then yes, I'd separate them. The interface would be com.foo.Bar and the implementations would be something like com.foo.bars.CrowBar, com.foo.bars.TaskBar for example. Obviously, if your implementations belong to different modules, then you would change it to com.foo.moduleX.bars.CrowBar or com.foo.bars.moduleX.CrowBar, depending on which system you're following.
Re-reading all this, it does sound kind of complicated, but probably the first sentence is the most important: don't follow packaging principles blindly, packages should help you find classes, not hinder you.
I prefer to limit the scope of my classes and methods to private or package protected wherever possible (so they don't clutter Eclipse's autocomplete:) which automatically means that packages can contain quite a few classes.
I do prefer to separate business data objects (DAO's) from their repositories/retrieval services, which are separated from business logic objects and views.
Sets of related functionality with no cross dependencies tend to go in their own artifact as I tend to reuse logic. Especially handy when you start playing with OSGi and independent services.
One thing is important, the publicly exported interface (public interfaces, enums and classes) need to be somewhat related so the package documentation shows some cohesion.
I am writing an application that will ship in several different versions (initially around 10 variations of the code base will exist, and will need to be maintained). Of course, 98% or so of the code will be the same amongst the different systems, and it makes sense to keep the code base intact.
My question is - what would be the preferred way to do this? If I for instance have a class (MyClass) that is different in some versions (MyClassDifferent), and that class is referenced at a couple of places. I would like for that reference to change depending on what version of the application I am compiling, rather than having to split all the classes referring to MyClassDifferent too. Preprocessor macros would be nice, but they bloat the code and afaik there are only proof of concept implementations available?
I am considering something like a factory-pattern, coupled with a configuration file for each application. Does anyone have any tips or pointers?
You are on the right track: Factory patterns, configuration etc.
You could also put the system specific features in separate jar files and then you would only need to include the appropriate jar alongside your core jar file.
I'd second your factory approach and you should have a closer look at maven or ant (depending on what you are using).
You can deploy the different configuration files that determine which classes are used based on parameters/profiles.
Preprocessor makros like C/C++ have are not available directly for java. Although maybe it's possible to emulate this via build scripts. But I'd not go down that road. My suggestion is stick with the factory approach.
fortunately you have several options
1) ServiceLoader (builtin in java6) put your API class like MyClass in a jar, the compile your application against this API. Then put a separate implementation of MyClass in a separate jar with /META-INF/services/com.foo.MyClass. . Then you can maintain several version of your application simply keeping a "distribution" of jars. Your "main" class is just a bunch of ServiceLoader calls
2) same architecture of 1) but replacing META-INF services with Spring or Guice config
3) OSGI
4) your solution
Look up the AbstractFactory design pattern, "Dependency Injection", and "Inversion of Control". Martin Fowler writes about these here.
Briefly, you ship JAR files with all the needed components. For each service point that can be customized, you define an Interface for the service. Then you write one or more implementations of that Interface. To create a service object, you ask an AbstractFactory for it, eg:
AbstractFactory factory = new AbstractFactory();
...
ServiceXYZ s = factory.newServiceXYZ();
s.doThis();
s.doThat();
Inside your AbstractFactory you construct the appropriate ServiceXYZ object using the Java reflection method Class.classForName(), and SomeClassObject.newInstance(). (Doing it this way means you don't have to have the ServiceXYZ class in the jar files unless it makes sense. You can also build the objects normally.)
The actual class names are read in from a properties file unique to each site.
You can roll your own solution easily enough, or use a framework like Spring, Guice, or Pico.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I thought about this awhile ago and it recently resurfaced as my shop is doing its first real Java web app.
As an intro, I see two main package naming strategies. (To be clear, I'm not referring to the whole 'domain.company.project' part of this, I'm talking about the package convention beneath that.) Anyway, the package naming conventions that I see are as follows:
Functional: Naming your packages according to their function architecturally rather than their identity according to the business domain. Another term for this might be naming according to 'layer'. So, you'd have a *.ui package and a *.domain package and a *.orm package. Your packages are horizontal slices rather than vertical.
This is much more common than logical naming. In fact, I don't believe I've ever seen or heard of a project that does this. This of course makes me leery (sort of like thinking that you've come up with a solution to an NP problem) as I'm not terribly smart and I assume everyone must have great reasons for doing it the way they do. On the other hand, I'm not opposed to people just missing the elephant in the room and I've never heard a an actual argument for doing package naming this way. It just seems to be the de facto standard.
Logical: Naming your packages according to their business domain identity and putting every class that has to do with that vertical slice of functionality into that package.
I have never seen or heard of this, as I mentioned before, but it makes a ton of sense to me.
I tend to approach systems vertically rather than horizontally. I want to go in and develop the Order Processing system, not the data access layer. Obviously, there's a good chance that I'll touch the data access layer in the development of that system, but the point is that I don't think of it that way. What this means, of course, is that when I receive a change order or want to implement some new feature, it'd be nice to not have to go fishing around in a bunch of packages in order to find all the related classes. Instead, I just look in the X package because what I'm doing has to do with X.
From a development standpoint, I see it as a major win to have your packages document your business domain rather than your architecture. I feel like the domain is almost always the part of the system that's harder to grok where as the system's architecture, especially at this point, is almost becoming mundane in its implementation. The fact that I can come to a system with this type of naming convention and instantly from the naming of the packages know that it deals with orders, customers, enterprises, products, etc. seems pretty darn handy.
It seems like this would allow you to take much better advantage of Java's access modifiers. This allows you to much more cleanly define interfaces into subsystems rather than into layers of the system. So if you have an orders subsystem that you want to be transparently persistent, you could in theory just never let anything else know that it's persistent by not having to create public interfaces to its persistence classes in the dao layer and instead packaging the dao class in with only the classes it deals with. Obviously, if you wanted to expose this functionality, you could provide an interface for it or make it public. It just seems like you lose a lot of this by having a vertical slice of your system's features split across multiple packages.
I suppose one disadvantage that I can see is that it does make ripping out layers a little bit more difficult. Instead of just deleting or renaming a package and then dropping a new one in place with an alternate technology, you have to go in and change all of the classes in all of the packages. However, I don't see this is a big deal. It may be from a lack of experience, but I have to imagine that the amount of times you swap out technologies pales in comparison to the amount of times you go in and edit vertical feature slices within your system.
So I guess the question then would go out to you, how do you name your packages and why? Please understand that I don't necessarily think that I've stumbled onto the golden goose or something here. I'm pretty new to all this with mostly academic experience. However, I can't spot the holes in my reasoning so I'm hoping you all can so that I can move on.
For package design, I first divide by layer, then by some other functionality.
There are some additional rules:
layers are stacked from most general (bottom) to most specific (top)
each layer has a public interface (abstraction)
a layer can only depend on the public interface of another layer (encapsulation)
a layer can only depend on more general layers (dependencies from top to bottom)
a layer preferably depends on the layer directly below it
So, for a web application for example, you could have the following layers in your application tier (from top to bottom):
presentation layer: generates the UI that will be shown in the client tier
application layer: contains logic that is specific to an application, stateful
service layer: groups functionality by domain, stateless
integration layer: provides access to the backend tier (db, jms, email, ...)
For the resulting package layout, these are some additional rules:
the root of every package name is <prefix.company>.<appname>.<layer>
the interface of a layer is further split up by functionality: <root>.<logic>
the private implementation of a layer is prefixed with private: <root>.private
Here is an example layout.
The presentation layer is divided by view technology, and optionally by (groups of) applications.
com.company.appname.presentation.internal
com.company.appname.presentation.springmvc.product
com.company.appname.presentation.servlet
...
The application layer is divided into use cases.
com.company.appname.application.lookupproduct
com.company.appname.application.internal.lookupproduct
com.company.appname.application.editclient
com.company.appname.application.internal.editclient
...
The service layer is divided into business domains, influenced by the domain logic in a backend tier.
com.company.appname.service.clientservice
com.company.appname.service.internal.jmsclientservice
com.company.appname.service.internal.xmlclientservice
com.company.appname.service.productservice
...
The integration layer is divided into 'technologies' and access objects.
com.company.appname.integration.jmsgateway
com.company.appname.integration.internal.mqjmsgateway
com.company.appname.integration.productdao
com.company.appname.integration.internal.dbproductdao
com.company.appname.integration.internal.mockproductdao
...
Advantages of separating packages like this is that it is easier to manage complexity, and it increases testability and reusability. While it seems like a lot of overhead, in my experience it actually comes very natural and everyone working on this structure (or similar) picks it up in a matter of days.
Why do I think the vertical approach is not so good?
In the layered model, several different high-level modules can use the same lower-level module. For example: you can build multiple views for the same application, multiple applications can use the same service, multiple services can use the same gateway. The trick here is that when moving through the layers, the level of functionality changes. Modules in more specific layers don't map 1-1 on modules from the more general layer, because the levels of functionality they express don't map 1-1.
When you use the vertical approach for package design, i.e. you divide by functionality first, then you force all building blocks with different levels of functionality into the same 'functionality jacket'. You might design your general modules for the more specific one. But this violates the important principle that the more general layer should not know about more specific layers. The service layer for example shouldn't be modeled after concepts from the application layer.
I find myself sticking with Uncle Bob's package design principles. In short, classes which are to be reused together and changed together (for the same reason, e.g. a dependency change or a framework change) should be put in the same package. IMO, the functional breakdown would have better chance of achieving these goals than the vertical/business-specific break-down in most applications.
For example, a horizontal slice of domain objects can be reused by different kinds of front-ends or even applications and a horizontal slice of the web front-end is likely to change together when the underlying web framework needs to be changed. On the other hand, it's easy to imagine the ripple effect of these changes across many packages if classes across different functional areas are grouped in those packages.
Obviously, not all kinds of software are the same and the vertical breakdown may make sense (in terms of achieving the goals of reusability and closeability-to-change) in certain projects.
There are usually both levels of division present. From the top, there are deployment units. These are named 'logically' (in your terms, think Eclipse features). Inside deployment unit, you have functional division of packages (think Eclipse plugins).
For example, feature is com.feature, and it consists of com.feature.client, com.feature.core and com.feature.ui plugins. Inside plugins, I have very little division to other packages, although that's not unusual too.
Update: Btw, there is great talk by Juergen Hoeller about code organization at InfoQ: http://www.infoq.com/presentations/code-organization-large-projects. Juergen is one of architects of Spring, and knows a lot about this stuff.
Most java projects I've worked on slice the java packages functionally first, then logically.
Usually parts are sufficiently large that they're broken up into separate build artifacts, where you might put core functionality into one jar, apis into another, web frontend stuff into a warfile, etc.
Both functional (architectural) and logical (feature) approaches to packaging have a place. Many example applications (those found in text books etc.) follow the functional approach of placing presentation, business services, data mapping, and other architectural layers into separate packages. In example applications, each package often has only a few or just one class.
This initial approach is fine since a contrived example often serves to: 1) conceptually map out the architecture of the framework being presented, 2) is done so with a single logical purpose (e.g. add/remove/update/delete pets from a clinic). The problem is that many readers take this as a standard that has no bounds.
As a "business" application expands to include more and more features, following the functional approach becomes a burden. Although I know where to look for types based on architecture layer (e.g. web controllers under a "web" or "ui" package, etc.), developing a single logical feature begins to require jumping back and forth between many packages. This is cumbersome, at the very least, but its worse than that.
Since logically related types are not packaged together, the API is overly publicized; the interaction between logically related types is forced to be 'public' so that types can import and interact with each other (the ability to minimize to default/package visibility is lost).
If I am building a framework library, by all means my packages will follow a functional/architectural packaging approach. My API consumers might even appreciate that their import statements contain intuitive package named after the architecture.
Conversely, when building a business application I will package by feature. I have no problem placing Widget, WidgetService, and WidgetController all in the same "com.myorg.widget." package and then taking advantage of default visibility (and having fewer import statements as well as inter-package dependencies).
There are, however, cross-over cases. If my WidgetService is used by many logical domains (features), I might create a "com.myorg.common.service." package. There is also a good chance that I create classes with intention to be re-usable across features and end up with packages such as "com.myorg.common.ui.helpers." and "com.myorg.common.util.". I may even end up moving all these later "common" classes in a separate project and include them in my business application as a myorg-commons.jar dependency.
Packages are to be compiled and distributed as a unit. When considering what classes belong in a package, one of the key criteria is its dependencies. What other packages (including third-party libraries) does this class depend on. A well-organized system will cluster classes with similar dependencies in a package. This limits the impact of a change in one library, since only a few well-defined packages will depend on it.
It sounds like your logical, vertical system might tend to "smear" dependencies across most packages. That is, if every feature is packaged as a vertical slice, every package will depend on every third party library that you use. Any change to a library is likely to ripple through your whole system.
I personally prefer grouping classes logically then within that include a subpackage for each functional participation.
Goals of packaging
Packages are after all about grouping things together - the idea being related classes live close to each other. If they live in the same package they can take advantage of package private to limit visibility. The problem is lumping all your view and persitance stuff into one package can lead to a lot of classes being mixed up into a single package. The next sensible thing to do is thus create view, persistance, util sub packages and refactor classes accordingly. Underfortunately protected and package private scoping does not support the concept of the current package and sub package as this would aide in enforcing such visibility rules.
I see now value in separation via functionality becase what value is there to group all the view related stuff. Things in this naming strategy become disconnected with some classes in the view whilst others are in persistance and so on.
An example of my logical packaging structure
For purposes of illustration lets name two modules - ill use the name module as a concept that groups classes under a particular branch of a pacckage tree.
apple.model
apple.store
banana.model
banana.store
Advantages
A client using the Banana.store.BananaStore is only exposed to the functionality we wish to make available. The hibernate version is an implementation detail which they do not need to be aware nor should they see these classes as they add clutter to storage operations.
Other Logical v Functional advantages
The further up towards the root the broader the scope becomes and things belonging to one package start to exhibit more and more dependencies on things belonging to toher modules. If one were to examine for example the "banana" module most of the dependencies would be limited to within that module. In fact most helpers under "banana" would not be referenced at all outside this package scope.
Why functionality ?
What value does one achieve by lumping things based on functionality. Most classes in such a case are independent of each other with little or no need to take advantage of package private methods or classes. Refactoring them so into their own subpackages gains little but does help reduce the clutter.
Developer changes to the system
When developers are tasked to make changes that are a bit more than trivial it seems silly that potentially they have changes that include files from all areas of the package tree. With the logical structured approach their changes are more local within the same part of the package tree which just seems right.
It depends on the granularity of your logical processes?
If they're standalone, you often have a new project for them in source control, rather than a new package.
The project I'm on at the moment is erring towards logical splitting, there's a package for the jython aspect, a package for a rule engine, packages for foo, bar, binglewozzle, etc. I'm looking at having the XML specific parsers/writers for each module within that package, rather than having an XML package (which I have done previously), although there will still be a core XML package where shared logic goes. One reason for this however is that it may be extensible (plugins) and thus each plugin will need to also define its XML (or database, etc) code, so centralising this could introduce problems later on.
In the end it seems to be how it seems most sensible for the particular project. I think it's easy to package along the lines of the typical project layered diagram however. You'll end up with a mix of logical and functional packaging.
What's needed is tagged namespaces. An XML parser for some Jython functionality could be tagged both Jython and XML, rather than having to choose one or the other.
Or maybe I'm wibbling.
I try to design package structures in such a way that if I were to draw a dependency graph, it would be easy to follow and use a consistent pattern, with as few circular references as possible.
For me, this is much easier to maintain and visualize in a vertical naming system rather than horizontal. if component1.display has a reference to component2.dataaccess, that throws off more warning bells than if display.component1 has a reference to dataaccess. component2.
Of course, components shared by both go in their own package.
I totally follow and propose the logical ("by-feature") organization! A package should follow the concept of a "module" as closely as possible. The functional organization may spread a module over a project, resulting in less encapsulation, and prone to changes in implementation details.
Let's take an Eclipse plugin for example: putting all the views or actions in one package would be a mess. Instead, each component of a feature should go to the feature's package, or if there are many, into subpackages (featureA.handlers, featureA.preferences etc.)
Of course, the problem lies in the hierarchical package system (which among others Java has), which makes the handling of orthogonal concerns impossible or at least very difficult - although they occur everywhere!
I would personally go for functional naming. The short reason: it avoids code duplication or dependency nightmare.
Let me elaborate a bit. What happens when you are using an external jar file, with its own package tree? You are effectively importing the (compiled) code into your project, and with it a (functionally separated) package tree. Would it make sense to use the two naming conventions at the same time? No, unless that was hidden from you. And it is, if your project is small enough and has a single component. But if you have several logical units, you probably don't want to re-implement, let's say, the data file loading module. You want to share it between logical units, not have artificial dependencies between logically unrelated units, and not have to choose which unit you are going to put that particular shared tool into.
I guess this is why functional naming is the most used in projects that reach, or are meant to reach, a certain size, and logical naming is used in class naming conventions to keep track of the specific role, if any of each class in a package.
I will try to respond more precisely to each of your points on logical naming.
If you have to go fishing in old classes to modify functionalities when you have a change of plans, it's a sign of bad abstraction: you should build classes that provide a well defined functionality, definable in one short sentence. Only a few, top-level classes should assemble all these to reflect your business intelligence. This way, you will be able to reuse more code, have easier maintenance, clearer documentation and less dependency issues.
That mainly depends on the way you grok your project. Definitely, logical and functional view are orthogonal. So if you use one naming convention, you need to apply the other one to class names in order to keep some order, or fork from one naming convention to an other at some depth.
Access modifiers are a good way to allow other classes that understand your processing to access the innards of your class. Logical relationship does not mean an understanding of algorithmic or concurrency constraints. Functional may, although it does not. I am very weary of access modifiers other than public and private, because they often hide a lack of proper architecturing and class abstraction.
In big, commercial projects, changing technologies happens more often than you would believe. For instance, I have had to change 3 times already of XML parser, 2 times of caching technology, and 2 times of geolocalisation software. Good thing I had hid all the gritty details in a dedicated package...
It is an interesting experiment not to use packages at all (except for the root package.)
The question that arises then, is, when and why it makes sense to introduce packages. Presumably, the answer will be different from what you would have answered at the beginning of the project.
I presume that your question arises at all, because packages are like categories and it's sometimes hard to decide for one or the other. Sometimes tags would be more appreciate to communicate that a class is usable in many contexts.
From a purely practical standpoint, java's visibility constructs allow classes in the same package to access methods and properties with protected and default visibility, as well as the public ones. Using non-public methods from a completely different layer of the code would definitely be a big code smell. So I tend to put classes from the same layer into the same package.
I don't often use these protected or default methods elsewhere - except possibly in the unit tests for the class - but when I do, it is always from a class at the same layer
It depends. In my line of work, we sometimes split packages by functions (data access, analytics) or by asset class (credit, equities, interest rates). Just select the structure which is most convenient for your team.
From my experience, re-usability creates more problems than solving. With the latest & cheap processors and memory, I would prefer duplication of code rather than tightly integrating in order to reuse.
First of all, I know how to build a Java application. But I have always been puzzled about where to put my classes. There are proponents for organizing the packages in a strictly domain oriented fashion, others separate by tier.
I myself have always had problems with
naming,
placing
So,
Where do you put your domain specific constants (and what is the best name for such a class)?
Where do you put classes for stuff which is both infrastructural and domain specific (for instance I have a FileStorageStrategy class, which stores the files either in the database, or alternatively in database)?
Where to put Exceptions?
Are there any standards to which I can refer?
I've really come to like Maven's Standard Directory Layout.
One of the key ideas for me is to have two source roots - one for production code and one for test code like so:
MyProject/src/main/java/com/acme/Widget.java
MyProject/src/test/java/com/acme/WidgetTest.java
(here, both src/main/java and src/test/java are source roots).
Advantages:
Your tests have package (or "default") level access to your classes under test.
You can easily package only your production sources into a JAR by dropping src/test/java as a source root.
One rule of thumb about class placement and packages:
Generally speaking, well structured projects will be free of circular dependencies. Learn when they are bad (and when they are not), and consider a tool like JDepend or SonarJ that will help you eliminate them.
I'm a huge fan of organized sources, so I always create the following directory structure:
/src - for your packages & classes
/test - for unit tests
/docs - for documentation, generated and manually edited
/lib - 3rd party libraries
/etc - unrelated stuff
/bin (or /classes) - compiled classes, output of your compile
/dist - for distribution packages, hopefully auto generated by a build system
In /src I'm using the default Java patterns: Package names starting with your domain (org.yourdomain.yourprojectname) and class names reflecting the OOP aspect you're creating with the class (see the other commenters). Common package names like util, model, view, events are useful, too.
I tend to put constants for a specific topic in an own class, like SessionConstants or ServiceConstants in the same package of the domain classes.
Where I'm working, we're using Maven 2 and we have a pretty nice archetype for our projects. The goal was to obtain a good separation of concerns, thus we defined a project structure using multiple modules (one for each application 'layer'):
- common: common code used by the other layers (e.g., i18n)
- entities: the domain entities
- repositories: this module contains the daos interfaces and implementations
- services-intf: interfaces for the services (e.g, UserService, ...)
- services-impl: implementations of the services (e.g, UserServiceImpl)
- web: everything regarding the web content (e.g., css, jsps, jsf pages, ...)
- ws: web services
Each module has its own dependencies (e.g., repositories could have jpa) and some are project wide (thus they belong in the common module). Dependencies between the different project modules clearly separate things (e.g., the web layer depends on the service layer but doesn't know about the repository layer).
Each module has its own base package, for example if the application package is "com.foo.bar", then we have:
com.foo.bar.common
com.foo.bar.entities
com.foo.bar.repositories
com.foo.bar.services
com.foo.bar.services.impl
...
Each module respects the standard maven project structure:
src\
..main\java
...\resources
..test\java
...\resources
Unit tests for a given layer easily find their place under \src\test... Everything that is domain specific has it's place in the entities module. Now something like a FileStorageStrategy should go into the repositories module, since we don't need to know exactly what the implementation is. In the services layer, we only know the repository interface, we do not care what the specific implementation is (separation of concerns).
There are multiple advantages to this approach:
clear separation of concerns
each module is packageable as a jar (or a war in the case of the web module) and thus allows for easier code reuse (e.g., we could install the module in the maven repository and reuse it in another project)
maximum independence of each part of the project
I know this doesn't answer all your questions, but I think this could put you on the right path and could prove useful to others.
Class names should always be descriptive and self-explanatory. If you have multiple domains of responsibility for your classes then they should probably be refactored.
Likewise for you packages. They should be grouped by domain of responsibility. Every domain has it's own exceptions.
Generally don't sweat it until you get to a point where it is becoming overwhelming and bloated. Then sit down and don't code, just refactor the classes out, compiling regularly to make sure everything works. Then continue as you did before.
Use packages to group related functionality together.
Usually the top of your package tree is your domain name reversed (com.domain.subdomain) to guarantee uniqueness, and then usually there will be a package for your application. Then subdivide that by related area, so your FileStorageStrategy might go in, say, com.domain.subdomain.myapp.storage, and then there might be specific implementations/subclasses/whatever in com.domain.subdomain.myapp.storage.file and com.domain.subdomain.myapp.storage.database. These names can get pretty long, but import keeps them all at the top of files and IDEs can help to manage that as well.
Exceptions usually go in the same package as the classes that throw them, so if you had, say, FileStorageException it would go in the same package as FileStorageStrategy. Likewise an interface defining constants would be in the same package.
There's not really any standard as such, just use common sense, and if it all gets too messy, refactor!
One thing that I found very helpful for unit tests was to have a myApp/src/ and also myApp/test_src/ directories. This way, I can place unit tests in the same packages as the classes they test, and yet I can easily exclude the test cases when I prepare my production installation.
Short answer: draw your system architecture in terms of modules, drawn side-by-side, with each module sliced vertically into layers (e.g. view, model, persistence). Then use a structure like com.mycompany.myapp.somemodule.somelayer, e.g. com.mycompany.myapp.client.view or com.mycompany.myapp.server.model.
Using the top level of packages for application modules, in the old-fashioned computer-science sense of modular programming, ought to be obvious. However, on most of the projects I have worked on we end up forgetting to do that, and end up with a mess of packages without that top-level structure. This anti-pattern usually shows itself as a package for something like 'listeners' or 'actions' that groups otherwise unrelated classes simply because they happen to implement the same interface.
Within a module, or in a small application, use packages for the application layers. Likely packages include things like the following, depending on the architecture:
com.mycompany.myapp.view
com.mycompany.myapp.model
com.mycompany.myapp.services
com.mycompany.myapp.rules
com.mycompany.myapp.persistence (or 'dao' for data access layer)
com.mycompany.myapp.util (beware of this being used as if it were 'misc')
Within each of these layers, it is natural to group classes by type if there are a lot. A common anti-pattern here is to unnecessarily introduce too many packages and levels of sub-package so that there are only a few classes in each package.
I think keep it simple and don't over think it. Don't over abstract and layer too much. Just keep it neat, and as it grows, refactoring it is trivial. One of the best features of IDEs is refactoring, so why not make use of it and save you brain power for solving problems that are related to your app, rather then meta issues like code organisation.
One thing I've done in the past - if I'm extending a class I'll try and follow their conventions. For example, when working with the Spring Framework, I'll have my MVC Controller classes in a package called com.mydomain.myapp.web.servlet.mvc
If I'm not extending something I just go with what is simplest. com.mydomain.domain for Domain Objects (although if you have a ton of domain objects this package could get a bit unwieldy).
For domain specific constants, I actually put them as public constants in the most related class. For example, if I have a "Member" class and have a maximum member name length constant, I put it in the Member class. Some shops make a separate Constants class but I don't see the value in lumping unrelated numbers and strings into a single class. I've seen some other shops try to solve this problem by creating SEPARATE Constants classes, but that just seems like a waste of time and the result is too confusing. Using this setup, a large project with multiple developers will be duplicating constants all over the place.
I like break my classes down into packages that are related to each other.
For example:
Model For database related calls
View Classes that deal with what you see
Control Core functionality classes
Util Any misc. classes that are used (typically static functions)
etc.