I'm not even sure if this is doable but I want to ask the community for their general opinion.
I have to solve a following problem:
My Project has 2 Layers, a Core layer and a Business layer.
This Core layer is providing the Business layer. At this moment Business classes can import Core classes and do whatever they want. Core classes can only import core classes and use their methods, the access to Business classes and their respective methods is forbidden.
I want to add a specific feature:
I don't want to give Core any normal access to the Business layer, but I want to create something like an interface or anything similar (I don't know how to express myself here cause I have no idea if its possible), that provides the Core classes some specific methods from Business classes to use.
Can anyone help me out, or at least give me some guidelines what to read, or where to search.
Thanks in advance for any support.
Edit:
I use Spring Framework with Seam and JBoss
What you are probably facing is the design of module dependency and circular dependency. In short, the Business methods that Core needs may have to be re-factored into a 'utils' module or a 'Business-Core' module that is then accessible by both. I am only guessing here.
In addition to automating builds, a build tool like Maven also encourages such modularization and dependency. It is not unusual for a project that started off as one module to be split into 3-4 modules by the time it is done.
This can be achieved by using AspectJ. You can write rules in AspectJ-syntax which will give build-time-errors if not enforced. See the article Archtectual Enforcement with Aid of AspectJ for an example.
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 am starting project which will use 3-tier architecture with REST API.
I would like to split each layer into separate module, so I definitely need at least 3 modules:
REST
BLL
DAL
What is the best approach to make dependencies between them:
1)
REST depends on BLL
BLL depends on DAL
DAL depends on nothing
2)
REST depends on nothing
BLL depends on REST
DAL depends on BLL
3)
REST depends on REST-BLL-Interfaces
REST-BLL-Interfaces depends on nothing
BLL depends on REST-BLL-Interfaces and DAL-BLL-Interfaces
DAL-BLL-Interfaces depenends on nothing
DAL depends on DAL-BLL-Interfaces
Third approach seems to be the most compatible with Dependency Inversion Principle but requires more modules.
How would You name those two additional modules?
I would keep your BLL code in a project called Services, your DAL code in a project called Repositories, and your interfaces and business objects(or entities) in a project called Core.
Your REST project should reference only Core (and Services for resolving dependencies). You program exclusively to interfaces. You can also employ the DI Principle here, as you stated.
Your Services and Repositories should each only depend on Core. These concrete implementations need only implement Core interfaces and act on Core entities.
Not only does this approach allow you to use DI, but it makes testing much easier. Additionally, none of your application will be tightly coupled to your concrete external dependencies (ie, a particular database implementation). This makes your entire application much more flexible and extensible.
Side note: I often include another project called Infrastructure to handle cross-cutting concerns such as logging. These concrete classes implement Core interfaces, just like my repositories and services, and can be called using interfaces.
You could introduce a fourth module common to all that has all interfaces and domain model, but that won't prevent REST calling DAL directly (it will compile at least).
I usually do it like that or go straight for the first option, and I don't worry about that as I'm counting on the my other co-conspirator developers to have some sense of architecture separation. I've in the past used 'architectural' aspects to prevent layer hopping, but you'd have to include aspect compiler support in your build/IDE to do that.
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 8 years ago.
Improve this question
Recently I came across this javalobby post http://java.dzone.com/articles/how-changing-java-package on packaging java code by feature.
I like the idea, but i have few questions on this approach. I asked my question but didn't get a satisfactory reply. I hope someone on StackOverflow can clarify my questions.
I like the idea of package by feature which greately reduces the time for moving across the packages while coding and all the related stuff will be at one place(package). But what about interactions between the services in different packages?
Suppose we are building a blog app and we are putting all user related operations(controllers/services/repositories) in com.mycompany.myblog.users package. And all blog post related operations(controllers/services/repositories) in com.mycompany.myblog.posts package.
Now I want to show User Profile along with all the posts that he posted. Should I call myblog.posts.PostsService.getPostsByUser(userId) from myblog.users.UserController.showUserProfile()?
What about coupling between packages?
Also wherever I read about package by feature, everyone says its a good practice. Then why many book authors and even frameworks encourage to group by layers? Just curious to know :-)
Take a look at uncle Bob's Package Design Principles. He explains reasons and motivations behind those principles, which I have elaborated on below:
Classes that get reused together should be packaged together so that the package can be treated as a sort of complete product available for you. And those which are reused together should be separated away from the ones those are not reused with. For example, your Logging utility classes are not necessarily used together with your file io classes. So package all logging them separately. But logging classes could be related to one another. So create a sort of complete product for logging, say, for the want of better name commons-logging package it in a (re)usable jar and another separate complete product for io utilities, again for the want of better name, say commons-io.jar.
If you update say commons-io library to say support java nio, then you may not necessarily want to make any changes to the logging library. So separating them is better.
Now, let's say you wanted your logging utility classes to support structured logging for say some sort of log analysis by tools like splunk. Some clients of your logging utility may want to update to your newer version; some others may not. So when you release a new version, package all classes which are needed and reused together for migration. So some clients of your utility classes can safely delete your old commons-logging jar and move to commons-logging-new jar. Some other clients are still ok with older jar. However no clients are needed to have both these jars (new and old) just because you forced them to use some classes for older packaged jar.
Avoid cyclic dependencies. a depend on b; b on c; c on d; but d depends on a. The scenario is obviously deterring as it will be very difficult to define layers or modules, etc and you cannot vary them independly relative to each other.
Also, you could package your classes such that if a layer or module changes, other module or layers do not have to change necessarily. So, for example, if you decide to go from old MVC framework to a rest APIs upgrade, then only view and controller may need changes; your model does not.
I personally like the "package by feature" approach, although you do need to apply quite a lot of judgement on where to draw the package boundaries. It's certainly a feasible and sensible approach in many circumstances.
You should probably achieve coupling between packages and modules using public interfaces - this keeps the coupling clean and manageable.
It's perfectly fine for the "blog posts" package to call into the "users" package as long as it uses well designed public interfaces to do so.
One big piece of advice though if you go down this approach: be very thoughtful about your dependencies and in particular avoid circular dependencies between packages. A good design should looks like a dependency tree - with the higher level areas of functionality depending on a set of common services which depend upon libraries of utility functions etc. To some extent, this will start to look like architectural "layers" with front-end packages calling into back-end services.
There many other aspect other than coupling for package design i would suggest to look at OOAD Priciples, especially package design priciples like
REP The Release Reuse Equivalency Principle The granule of reuse is the granule of release.
CCP The Common Closure Principle Classes that change together are packaged together.
CRP The Common Reuse Principle Classes that are used together are packaged together.
ADP The Acyclic Dependencies Principle The dependency graph of packages must have no cycles.
SDP The Stable Dependencies Principle Depend in the direction of stability.
SAP The Stable Abstractions Principle Abstractness increases with stability.
for more information you can read book "Agile Software Development, Principles, Patterns, and Practices"
Are there any technical Design-by-Contract solutions for Java projects similar to XINS? I'm looking for projects/frameworks that enforce developers to first author a contract for their application and then code within the boundaries of that contract, really using the contract to the full potential. I'm looking for something that, like XINS, generates code (server- and client-side, unit tests, stubs) and documentation (OpenDocument, HTML, test forms) from that contract, with a runtime component that validates the contract.
The contract can be anything, e.g. WSDL or a bunch of XML files. Integration with Spring would be nice to have.
Note that I developed XINS in the past (not the current maintainer anymore, though), and I'm wondering what similar solutions exist and how they compare.
As far as I understand Spring Web Services project promotes the approach you described. It's even described in details in their tutorial. The idea is to describe data contract manually and create web services based on this description. Spring framework provides quite a lot of different infrastructure classes to make this task much easier to solve.
We have this constant discussion in our project as to the granularity of our maven modules. We have come to agree that there may be differences in the needs of a framework (like spring) and an in-house application that is always deployed monolithically.
We also agree that it's fairly sensible to hide implementation details of adapters to external systems behind a separate API module, so the implementation classes don't bleed into the classpath of the main implementations.
as
But that's as far as we go. It's a web project so we have modules like "web", "core" and "adapter(s)". We have multiple backends, but we don't require plugability.
What criteria do you use for modularizing in maven ? Which modules do you make for web projects ?
In my opinion, the project division should be pretty fine grained, even for "only a webapp".
I would make separate projects for the data access layer interfaces and implementation, business layer interfaces and implementation, and the webapp itself. I would also make atleast one "commons" project for containing code relevant to more than one of the other projects. But this is just the beginning. I would not hesitate to extract a commons-util project for utility classes relevant regardless of the application that is being developed (String, Date, Reflection, etc). I would also make a project for useful utilities when doing testing (commons-test). And that's just the next step ... ;)
If I wrote generally useful code relevant to hibernate, I would put it in a hibernate-utils project. Useful Spring utilities would go in a spring-utils project etc. When doing this, many projects will only contain a single or a few packages, and the packages will commonly contain few classes.
My reasoning for doing this, is that it helps me think about the code I write. Is this REALLY business logic, or is it general String manipulation, Date manipulation, Hibernate specific logic etc? My layers become cleaner, and it becomes harder to get circular dependencies between packages and projects (we don't want those). In addition, it becomes much easier to reuse code in other projects. There will always be other projects...
I have also found that it is easier for new developers to get a hang of the structure, because the projects become smaller and more manageable; it's easier to start coding when you feel you don't have to under stand everything.
As a last advantage to the fine grained approach, build times reduce because you don't have to build everything every time.