I'm writing some simple DAOs in Java using JDBC (no Spring, Hibernate or anything else).
Is it better to put the implementation DAOs in the same package as their interfaces or to put them in a sub-package?
Example:
com.mycompany.myproject.dao.MyDao
com.mycompany.myproject.dao.MyDaoImpl
OR
com.mycompany.myproject.dao.MyDao
com.mycompany.myproject.dao.impl.MyDaoImpl
If you suggest the sub-package structure, what would you suggest as a sub-package name? .impl? .sql? .jdbc?
Realistically, I'm not going to have multiple implementations. Am I over-engineering this?
When designing an application there is no standard way of structuring in packages, experience is what usually helps every one to decide what are the appropriate names for our packages.
About packaging implementations of your interfaces in the same package or in a different one just think about how Java itself is structured: usually an implementation class is packaged in the same package that its interface, but is not all the times.
If you were about to have several implementations of the same DAO's then it would make sense having them structured in .jdbc, .jpa or .jdo sub packages. If your are only going to have one implementation both of the options you enumerate make sense in some way (same package or a .impl sub package).
Regarding over-engineering I would recommend you this article. Even though you are going to have just one implementation of your DAO's, it would make sense to have them defined as an interface and implementation as that will help you in a potential future to rewrite your DAOs for other frameworks whilst the code that makes use of them keeps unchanged.
At the end it's up to you (or you and your peers) to reach a consensus and make the decision that makes more sense in your specific case.
EDIT
An application usually has one implementation per DAO interface and that isn't over-engineering at all, it simply doesn't make sense to have the same DAO interface implemented for JPA and for JDO. Some of the purposes of using the interface/implementation pattern is to ease re-factoring, testing by means of mock objects, etc..
P.S.: I usually rely on JDepend to distribute my application classes in packages avoiding cycles as most as I can.
I don't think either is better, but in this case I prefer the first alternative. It would be in line with having ArrayList, LinkedList, etc. , in the same package as List.
When using additional frameworks, such as hibernate I prefer the second option with MyDao and HibernateDao as the implementor.
I would go with your second option (although none is really better), because you can see immediately in your imports if an impl is imported and refactoring would be simpler if you want to move your impl in another project.
This is not over-engineering. There are multiple advantages to use DAO:
It improves the quality of your code by decoupling database access from other considerations
Testing your code is made easier and you can test it with a finer grain.
If some day, you find out that Hibernate is actually a lot easier for you, it won't impact the rest of your code.
Namespaces and packages only exist to prevent collisions. Neither is preferable as long as they are unique.
One purpose of packages is to improve readability for the other programmers on your team. Generally, I put the implementation in the same package as the interface, because that is the obvious place to look, and in most cases, the DAO implementation is simple. If your implementation is complex, then you should find a framework that is appropriate for your application.
Other reasons to consider a separate package include: if you are writing a library that will be used by other groups, or if you want to support multiple implementations.
Related
I've been reading a lot about package-by-feature naming convention. So I've decided to give it a try in a new project. However, I'm not sure how it should be named my packages that will be used by most of my classes, since I'm using a huge framework, such as Spring and Hibernate, for example.
This is how handle our Spring contexts classes:
And our database access class, the one that manages connections and so on.
I've a draft about this: using a common package for these frameworks, like:
com.company.project.common.spring
com.company.project.common.database
But I'm afraid that this still looks like package-by-layer a bit. :)
How the packages that will be accessed by my feature classes should be created ?
The common recommendation is "package by feature, not layer". What I often do is "package by feature, then layer". I also think that top-level packages should be "feature"-based (functional components, whatever). But I also like to have my layers separated into sub-packages.
From my point of view, framework-related code does not per se constitute "features" (as in "important, high-level aspects of the problem domain"), therefore package-by-feature is does not make much sense here. But still, this is important code and you need an approach to structure it.
I am normally use two approaches:
If I need to extend or augment libraries I'm using, I structure packages parallel to the package structure of the library. For instance if I'd need to implement some new number formatter for Spring, I'll probably name the package com.acme.foo.springframework.format.number, parallel to org.springframework.format.number.
However if I need to implement common base classes for layers of features, this would be probably something like com.acme.foo.common.<layer>. For instance if we have com.acme.foo.<feature>.dataaccess packages for data access layer of some feature, com.acme.foo.common.dataaccess could hold base classes for data access layers of all features.
Both approaches are used in parallel. You just have to decide whether some class is a framework or library extension (can you imagine using it outside this project?) or is it closer to the layers of your project.
I really wonder that put an Interface and a (Implemented) class in same package or separate is better. I usually put them in same package since I believe it is more convenient to compare.
But couple of days ago, I had an opportunity to use apache GenericObjectPool. Then I found such a package structure like org.apache.commons.pool.impl.
After all, my question is when should I use former one and when should I use the other. Thanks for your sincere answers in advanced:D
One of the tenets of composition is that interfaces are separated from their implementation.
Therefore it doesn't make much sense to constrain interfaces and their implementations to the same package.
(On a system I work on the interfaces are placed in a common area - loosely based on a concept of an interface repository).
If use interfaces just to lower the coupling, you can put interface and implementation into the same package. If you primarily count with more implementations if the interfaces, you should put them in separate package. This really depends on your design and I don't think there is a strict rule. Generally you should design you application as simple as possible and do the refactoring later. So when you start, you can put the implementation into the same package and only when it seems to be needed, you should split it.
If you define the responsibility of a package by its interfaces and classes, you attempt to abstract from concrete implementations. Hence, your package should consist of public types only.
If you continue to provide a default implementation for your package, I do not see any reason why not to put them into the same package. But I would always suggest to put your implementation into a separate project or more specific, to provide the API of your package and the implementation as two different artifacts (for example, jar-files).
Doing things this way, you support the following important aspects of abstraction:
replacement of one implementation with another
ensuring that client code depends only one the API and not the implementation (by adding only the API artifact to the clients classpath)
I have a module1 (GUI) and a module2 (Ordering).
From module1 I need to access the OrderingService found in module2.
I can of course create an OrderingService interface and an OrderingServiceImpl as a concrete implementation. This is a good practice in relation to Dependency Inversion Principle (DIP).
From my knowledge in Java I can benefit from module decoupling (I can change OrderingServiceImpl but module1 will not be affected and RECOMPILED) and I can use dependency injection in Spring to automatically use the right implementation. Regarding TDD I don't think you really need to create a OrderingServiceMockImpl because you can use a Mocking framework to mock the concrete class OrderingServiceImpl.
When we only have a single concrete implementation is module decoupling the only real benefit? I see in practice a lot of developers that always create an interface but don't really use more then one concrete implementation and I'm trying to figure out if there is something more to it or not.
I can't just accept the concept create interfaces "hoping" you will benefit from them later on. Isn't more pragmatic to change the code to an interface when you really have two different implementations?
Also I would also like to understand this from a PHP point of view, because code compilation is not an issue in dynamicly typed languages.
The benefit of using interfaces is to let you work on smaller pieces of your system independently, in terms of testing, of course, but also in terms of the amount of details you need to concentrate on to write the code and to understand it when you look at months later. In some languages there are code management benefits too but this is not the primary motivation for using interfaces.
Let's change your example a little bit, because I would never start with the UI. Assume I am building the OrderingService which need a repository for storing and retrieving orders.
I would always create an interface for that repository, even if it is totally unlikely that I will ever have two implementations for it. The reason for creating it, that I do not need or want real data access at this stage of the development. What I do is "programming by wishful thinking". I imagine there would be this magic contraption that makes it possible to store and retrieve my orders. I specify how I imagine this as an interface. In my tests I mock the interface and can build the OrderingService without even touching anything DB related yet.
I do the same with other dependencies that are adapters to the "outside world" (repositories, clients for calling other services, event publishers, etc).
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 recently looked at a Java application which had a very fine-grained package structure. Many packages only contained one or two classes and many sub packages. Also many packages contained more sub packages than actual classes.
Is this a good or a bad thing?
IMO, it is a bad thing, though not a real show-stopper in terms of maintainability.
The disadvantages are that it makes classes harder to find, and that it makes the package names more verbose. The former applies more when you are not using an IDE.
It could be argued that it helps modularization in conjunction with "package private" scoping. But conversely, you could also argue that over-packagization actually does the opposite; i.e. forcing you to use public where you wouldn't have had to if you'd been less fine-grained / pedantic.
The actual number of types that end up in one particular package is not that important. It is how you arrive at your package structure.
Things like abstraction ("what" instead of "how", essentially "public" API), coupling (the degree of how dependent a package is on other packages) and cohesion (how interrelated is the functionality in one package) are more important.
Some guidelines for package design (mostly from Uncle Bob) are for example:
Packages should form reusable and releasable modules
Packages should be focussed for good reusability
Avoid cyclic dependencies between packages
Packages should depend only on packages that change less often
The abstraction of a package should be in proportion to how often it changes
Do not try to flesh out an entire package structure from scratch (You Are Not Going To Need It). Instead let it evolve and refactor often. Look at the import section of your Java sources for inspiration on moving types around. Don't be distracted by packages that contain only one or a few types.
I think finer grained package structure is a good thing. The main reason is it can help minimize your dependencies. But be careful... if you break things up too much that actually belong together, you will end up with circular dependencies!
As a rule of thumb, I usually have an interface (or group of related interfaces) in a package. And in subpackages I will have implementations of those interfaces (instead of having all the implementations in the same package). That way a client can just depend on the interface and implementation of interest... and not all the other stuff they don't need.
Hope this helps.
It is subjective, of course, but I generally prefer to decide my packages in a way they would contain at least 3-4 classes, but not more than about 13-15. It makes understanding better, while not cluttering the project. For others it might be different, though.
In case a package grows more than 13-15 classes, a subpackage is asking to emerge.
A package is a unit of encapsulation.
Ideally, it exposes a public API via interface(s) and hides implementation detail in package private classes.
The size of the package is therefore the number of classes needed to implement the public API.
There is also the magical number 7 +/- 2. Within physiological circles it has been shown that this is a basic limit on our ability to comprehend a given set of things. How much we can keep in short term memory and process at the same time before our brains need to start swapping. It is not a bad rule of thumb I've found when coding, ie once a package starts getting bigger than 10 classes it is time to think seriously about splitting it up, but below 5 packages it is really not worth it. Also applies well to things like menu organisation. See Millers paper, or google.
When writing from scratch my way is to begin all classes in the root package (com.example.app1). When there is a certain amount of interrelated classes that "do a whole thing" is time to create a package. After some time developing helper classes may go to a generic package (ex. com.example.app1.misc, com.example.app1.utils) to unload the root package.
So i try to keep clean the root package.
Fine-grain is not bad but as other said often refactoring produce a compact package structure.