How to organize dependencies in 3-tier architecture - java

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.

Related

Package structure by layer or feature in maven multi module project?

I have been reading about why it is more convenient to structure the packages by functionality. I understand that it has greater modularity and that it is easier to navigate in the packages.
However, what happens with projects with modules by layers?
For example:
|example-webapp (com.company.webapp.feature1)
|-example-service (com.company.service.feature1)
|-example-data (com.company.data.feature1)
In this case, modularization with maven already separates the project by layers and internally by functionality, however the functionality is distributed in all layers, which I understand reduces the modularity. But in my opinion it is much more reusable, because if at some point you want to implement an API for example, you simply reuse the service and data modules.
So, in multi module maven project how can I strcuture by feature?
|example-webapp (com.company.feature1)
|-example-service (com.company.feature1)
|-example-data (com.company.feature1)
It is advisable not to consider the layers?

Facade of services in Spring

I'm working on my first app in Spring and I have a design problem. I've created a few services that I'd like to use through a few facades (is it good idea?).
I'd like to have structure like this
/services
/facades
/interfaces
**facades**
/implementations
**sampleFacades**
/interfaces
**services**
/implementations
**sampleServices**
with package-private services (interfaces and implementations). Is it possible or I have to put all classes to one package?
The Facade Pattern is meant to create a simplified and dedicated access to more complicated code.
Typically you would have an API created by someone else and you would then create your own custom API to consume the other.
In this case you seem to be creating façades to Services in within the same Spring Applicaiton, which to me does not really make sense.
Why create façades when you have control over the service definitions?
If there is a need for a façade for your own service, perhaps they are not defined at the right level of granularity?
Note that some of the complexity of the Services should be addressed by other patterns such as Data Access Objects coordinated by the Services.
Regarding your question on putting all the classes in the same package, consider the Bounded Contexts of Domain Driven Design and organize your code around the domain instead of implementation details.

Designing java project for monoliths and microservices at same time

I would like to know how you divide project modules in java for monolith with possibility of transforming modules to micro-services later?
My personal naming looks like this:
com.company.shopapp.product
...product.domain (ddd, services, repositories, entities, aggregates, command handlers - everything with package scope)
...product.api (everything with public scope)
...product.controller (CQRS endpoints for commands in web perspective - (package scope))
...product.query(CQRS - package scope)
com.company.shopapp.sales
- domain
- api
- controller
- query
What we have here is basically product management context and sales context as packages.
Modules communicate each other using public interfaces (api package) only. In my project I use "..api.ProductFacade" to centralize communication points.
When my "sales" module grow i will turn it into microservice by implementing "..api.ProductFacade" interface as a "rest" or "soap" client and on the other side I will create Endpoint/RestController based on ProductFacade interface.
Package "com.company.shopapp.product.api" will be transformed into extended library and added to both projects.
Edit:
I can achive this out of the box using #Feign library.
https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-feign.html#spring-cloud-feign-inheritance
The whole idea feels nice, but maybe you have better way to design project and ensure that breaking it into micro-services will not break whole application.
I think your module structure is good. But I would suggest you create a real 'multi module' project (link). This way, using code from another module will generate a compile-error. This will help you to keep your good intentions!
In order to do this, you'll have to split each module in a private (implementations) and public (api, only interfaces) module (By doing this, you don't need an 'api'-package).
An implementation module can depend on any public-module, but not a private-module.
If you wire your application together in the private module, with dependency injection, the private modules will have no 'internal' dependencies!
The private modules will not have any 'compile-time' dependencies, only 'runtime' dependencies.
Here quick module dependency graph:
I hope you find this usefull!
Edit:
You will need an extra module only to bootstrap the application!
TLDR: Think components and modules separately and establish their "touch points"
Modules, as in your example, look like cross-cutting structure, which corresponds well enough to the recommended microservice practice. So, they can all be parts of a single microservice. And if you are going to use DDD, than you'll want to include a bounded context name in your package path.
In my own source code I usually separate (at the top level) modules like config (to load and parse, well, config), functional for the functional core, domain model, operational for managing concurrency, Akka actors structure, monitoring and so on, and adapters, where all API, DB and MQ code lives. And, at last, module app, where all is launched and interfaces are bound to implementations. Also, you usually have some utils or commons for lower level boilerplate, algorithms and so on.
In some architecture schools there is explicit separation between modules and components. While the former are parts of the source code structure, the latter are runtime units, which consume resources and live in their specific way.
In your case microservices correspond to such components. These components can be run in the same JVM - and you get a monolith. Or they can be run in a separate JVM on a (maybe) separate host. Then you call them microservices.
So, you need to:
make each component's source code autonomous so that it could be launched in a separate runtime space (like classloader, thread, threadpool, actor system subtree). Hence, you need some launcher to bring it to life. Then you'll be able to call it from your public static void main(...).
introduce some modules in your code that would hold semantics of an individual component each. So that you could understand a component's scope from the code.
abstract communication between components, so that you could use adapters (source code modules) to talk over a network, or to use intra-JVM mechanisms like procedure call or Akka's message passing.
I should notice that on the lower levels you can use common source code modules in your components, so they can have some intersections in code. But on the higher level source code would be distinctive, so you can split it into modules according to components.
You can use Akka and run each of your components in a supervision subtree, where the subtree's supervisor is your component's main actor. Then that main actor definition would be your component's main module. If you need to let components communicate, you should pass corresponding ActorRefs to adapters as a config param.
You tell about centralising communication points, but in my opinion, if you stick to microservices paradigm and high level of autonomy for your components, then for every API call somebody has to own a contract. Enter different DDD bounded context interaction patterns. If you leave it in some centrally managed module, which every component should use, then that's a case of API governance. As long as you are the only maintainer, that may be convenient. But when different developers (or even teams) take their parts, you'll need to make this decision once again considering new conditions.
When later you take components apart - then you'll pass URL to adapters instead of ActorRefs.
Microservices compound by functionality and degree of connectivity.
I used this approach:
com.company.product:
possible big service:
config
services
domain
etc
possible second big service:
config
services
domain
etc
config
services // which likely never be separated
domain // common domain
etc
When split project you analyze new common depencies seeing by packages, exclude common library, copy project for each microservice, delete unneccessary code, perhaps change services implementations (for example, if "possible big service" uses "possible second big service"), configurations and build.
"Big" in that context means full-fledged functional implementation of something, what could be horizontally scaled, or need to be microservice for other reasons.

Java calling methods from restricted layer

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.

Architecture Concerns

My domain classes and persistance logic (Hibernate) are in one project called model. This jar is included within all of my apps.
Packaged com.company.model & com.company.persistance
Another Utils.jar - contains DateTime, String, Thread, etc general helper classes. This again is included within all of my apps.
Packaged com.company.utils
I have a CXF/Spring app that exposes services for manipulating my data. CRUD functionality, ALL other common functions. This is the 'way in' to my database for any app designed.
Packaged com.company.services and running on Glassfish app server
I have other apps that use the web services (Spring injected) to manipulate my data. Including a web app that will use YUI widgets and the XML/JSON from the web services for a nice smooth UI.
I understand its not really a question! I suppose Im looking for confirmation that this is how others are designing their software. If my architecture makes good, logical sense! Obviously there are security concerns - I will want some applications allowed to only access service x. I will address these later.
Sounds good.
It depends also of the type of application you're developing and the specific requirements for that ( it has to be deployed every week, it has to be deployed in several locations etc )
But so far sounds good enough.
Looks like you can formulate a question from here in the future for some specific scenario.
Since this is not a question, mine is not really an answer. CW
My only comment would be to put the persistence and Hibernate classes into a separate module; so that the model module can be purely beans/POJO/your domain classes.
Here's how I've organized a few multi-module projects before
project-data - contains domain classes and DAOs (interfaces only)
project-services - "Business logic" layer services, makes use of DAO interfaces.
Depends on project-data.
project-hibernate - Hibernate implementation of DAO interfaces.
Depends on project-data.
Conceivably if I were to use some other sort of data-access method I would just create a separate module for that. Client apps could then choose which modules to be dependent on.
Only suggestion I might have is that when you're creating service/models that you group them by subpackage name. ie
com.company.model.core
com.company.service.core
com.company.model.billing
com.company.service.billing
Also, be careful to ensure that no controller code (manipulating your UI) ends up in the services.

Categories