Is there an acceptable way to keep these layers/dependencies separate? - java

I am currently struggling with whether or not I've achieved a good level of separation, or if I've missed the point somewhere, as I am relatively new to learning the disciplined side of development...
My goal when I started was to create a layer that was agnostic of any persistence mechanism - I called this data-api. I then implemented these interfaces using JDO, and called this project data-jdo. The logic layer ideally talks only is aware of data-api.
This is the point where I'm not sure what makes sense. The business logic layer has to be invoked somehow, right? So is the expectation that the implementation of the data-api (data-jdo, or something else depending on experimentation) is provided (appropriate to say/do injected?) by the invoker?
So the goal would be to (largely for experience and not for productivity) maybe, implement a data-jpa package that could be substituted in place of data-jdo. So the topmost layer (a web service, generic main method as part of a tool, unit tests, whatever) are the ones to make the choice which implementation to use.
Should I be using some framework like Spring to allow me to choose which implementation of my data-api is used, via XML?
Sorry if that's a little vague... I guess the root question is, at what point does the consumer of an API depend on, supply, or become paired with, the implementation of that API? If the answer is or should be "never" then what is used to make sure everything is available at runtime and how does the consumer get an instance of whatever the "API" is describing with only interfaces?

I come from a .net background - not a Java one, so I'm afraid I can't help you with Java specifics.
The business logic layer has to be invoked somehow, right? So is the expectation that the implementation of the data-api (data-jdo, or something else depending on experimentation) is provided (appropriate to say/do injected?) by the invoker?
Yes. In the .Net world I use a Factory (as in an instance of the Factory Pattern) that dynamically returns the data provider implementation (which one of those to use is set by config). The data provider is returned by the factory as an 'object' and it's up to the calling business logic code to cast it to the correct type - as specificed by the interface that the business logic is working against.
I'v egot (another!) article on Dependency Injection for .Net which might help explain with some of the issues, but I'm sure there are good java based ones around somewhere.
Should I be using some framework like Spring to allow me to choose which implementation of my data-api is used, via XML?
Probably. I'd say spend your time getting to grips with the concepts first, worry about "best practice" after that. FYI, I learnt AJAX the hard way - by writting all the code myself. These days I'd run straight to a good framework, but I only think I have the confidence to do that after having really grokked the basics by doing some hard graft at the coal-face :)
... If the answer is or should be "never" then what...
Yeah - it's never. Use a Factory.

Your data-api is a DAO interface layer, that's all your business (aka service) layer should know about persistence. And the presentation layer or any other layer above the business layer shouldn't have any "knowledge" of the DAO layer underneath.
To achieve that, relying on a framework like Spring is a good idea. The top level layer loads an application context which contains all the information for the framework to load the appropriate implementation.
For example, you could load applicationContext.xml from the front-end to use data-jdo, and load testApplicationContext.xml from the unit tests to use data-jpa.

Related

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.

Interface usage in Java and PHP in case of GUI calling a module

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).

What is the point of dependency injection as used in Spring?

I have been reading the book Spring in Action for a few weeks now to learn about the spring framework. I have about 2 years of programming experience mostly in java with some distractions here and there in Ruby and Python.
After reading the first few chapters, I didn't quite get what the big deal is about dependency injection in spring. I was expecting a AHAAA moment but didn't quite experience that yet. I'm sure I'm missing something important.
Why would I want to wire my beans in xml rather than instantiating them the good old way with the = new myclass();
I understand I can wire beans in the xml via constructor args and properties as well as configure datasources in spring so that I can hide away connection details in an xml file. But why? There is more to this especially when it comes to good software design. Can some one explain the big deal?
Three Words: INVERSION OF CONTROL
In a nutshell:
As soon as you instantaniate "the good old way" you create tight coupling, e.g.: your controller depends on a specific template engine, your entities on a concrete database layer, etc. And that's something you want to prevent and where the dependency injection container (DIC) comes in very handy. It manages your services and you don't really have to care anymore about specific implementations as long as those implement the same interface.
Imagine a simple storage layer class called InMemoryLayer that gets instantiated by you when need it. Now you want to switch it for an awesome new open-source github solution called SuperSecretRemoteCloudLayer. Normally you would now hit "Search and Replace" in your IDE of choice and replace all occurrences of InMemoryLayer with the SuperSecretRemoteCloudLayer. But that's not really handy and quite errorprone, why would you want to do all that hard work by hand? The DIC can do that for you and all you need to take care of, is that both *Layer implement the same interface (so your application won't break).
Spring's big deal is more about dependency injection, not XML-based configuration. As others have noted, Spring has been moving away from XML-based configuration. But DI is core to Spring.
The a-ha is that DI offers a different model for linking components together. Instead of components creating each other directly (and thus being tightly coupled), the components stop doing that, and you inject the linkages from a central location. It turns out that this helps with testing and transaction management in particular.
You don't truly appreciate Spring until you've had to do things the hard way. The hard way being maintaining multiple large projects without a coherent framework. If you have 4 big enterprise wide applications that all have their own way of starting themselves, and managing resources, you're in for a headache. If you know that each application uses spring, then just look for the application context xml! This also makes it incredibly easy to setup a new context for different environments, and test cases, all without mucking up your code base.

Maintaining Clean Architecture in Spring MVC with a data-centric approach

Maintaining Clean Architecture in Spring MVC with a data-centric approach
I'm trying to map out the architecture for the front-end of a new Java-based web app (portal type application) we are making at work. I want to get this right from day one, and I would like to kick off a discussion here to help me implement Uncle Bob's Clean Architecture in my architectural design.
Here's a quick run-down of our tech stack, top to bottom (the technology isn't importance, the structure is):
Oracle Database
Oracle Service Bus exposing services using WSDLs
JAX-WS generated Java-classes from the WSDLs (let's call this the "generated service layer")
A Domain module consisting of POJOs mapped to the generated data objects
A Consumer-module exposing the "generated service layer" to the front-end application
A Spring MVC based front-end module using FreeMarker to render the views
A key point:
In particular, the name of something declared in an outer circle must not be mentioned by the code in the an inner circle. That includes, functions, classes. variables, or any other named software entity.
Attempting to adhere to Bob's Clean Architecture, I've gone back and forth a bit with myself regarding where to place the application logic, namely the "Use Case"-layer in his architecture.
Here is the approach I've come up with:
Layer 1 - Entities
Entities encapsulate Enterprise wide business rules.
This is where our Domain module containing the domain-objects lives, these are self-containing objects with minimal dependencies on each other. Only logic pertaining to the objects themselves may live on these domain objects, and no use-case specific logic.
Access to our database is exposed via WSDLs using a service bus that transforms the data, as opposed to an ORM like JPA or Hibernate. Because of this, we do not have "entities" in the traditional sense (with Ids), but a data-centric approach making this layer a data access layer, presented to the rest of the application by the Consumer-module.
Layer 2 - Use Cases
The software in this layer contains application specific business rules.
This is where logic specific to our application's use cases lives. Changes to this layer should not affect the data access layer (layer 1). Changes to the GUI or framework implementation (Spring MVC) should not affect this layer.
This is where it gets a little tricky:
Since our data access layer (in layer 1) must be kept clean of application logic, we need a layer that facilitates use of that layer in a fashion that suits the use cases. One solution I've found to this problem is the use a variant of the "MVVM-pattern" that I choose to call MVC-VM. See below for an explanation. The "VM"-part of this lives in this Use Case-layer, represented by *ViewModel-classes that encapsulate this Use Case-specific logic.
Layer 3 - Interface Adapters
The software in this layer is a set of adapters that convert data from the format most convenient for the use cases and entities, to the format most convenient for some external agency such as the Database or the Web.
This is where the MVC-architecture of our GUI lives (the "MVC" in our "MVC-VM"). Essentially this is when the Controller-classes get data from the *ViewModel-classes and puts it in Spring MVC's ModelMap ojects that are used directly by the FreeMarker-templates in the View.
The way I see it, the servicebus would in our case also fall in under this layer.
Layer 4 - Frameworks and Drivers
Generally you don’t write much code in this layer other than glue code that communicates to the next circle inwards.
This layer is really just a configuration-layer in our application, namely the Spring configuration. This would for example be where we specify that FreeMarker is used to render the view.
Model View ViewModel Pattern
MVVM facilitates a clear separation of the development of the graphical user interface (either as markup language or GUI code) from the development of the business logic or back end logic known as the model (also known as the data model to distinguish it from the view model). The view model of MVVM is a value converter meaning that the view model is responsible for exposing the data objects from the model in such a way that those objects are easily managed and consumed.
More on the MVVM-pattern at Wikipedia.
The MVC-VM roles would be fulfilled in our application like so:
Model - represented simply by the ModelMap datastructure in Spring MVC that is used by the view templates.
View - FreeMarker templates
Controller Spring's Controller-classes that directs HTTP URL requests to specific handlers (and as such functions as a FrontController). The handlers in these classes are responsible for fetching data from the use case-layer and pushing it out to the view templates when showing data(HTTP GET), as well as sending data down for storing (HTTP POST). This way it essentially functions as a binder between the ViewModel and View, using the Model.
ViewModel - These classes are responsible for 1) structuring data from the data access layer in a fashion that is usable by the View and 2) treat data-input from the View. "Treat" means to validate and to break down the data so that it can be sent down the stack for storing. This layer would take form as <UseCase>VM-classes in a viewmodel package in our Spring MVC front-end module.
A key component here is the implicit binding that happens in Spring MVC between ModelMap and the FreeMarker-templates. The templates only use the model (ModelMaps), where the controller has put the data in a format it can use. That way we can make templates like so:
<body>
<h1>Welcome ${user}!</h1>
<p>Our latest product:
${latestProduct.name}!
</body>
I apologize for the verbose explanation, but I could not explain this (relatively simple) architecture in fewer words.
I would greatly appreciate some input on my approach here - am I on the right track? Does the MVC-VM thing make sense? Am I violating any Clean Architecture Principles?
There are of course many solutions to this, but I am trying to find a solution that is 1) not over-engineered and 2) adheres to the principles of Bob's Clean Architecture.
Update:
I think the key issue that puts me off here is what form the "Use case" layer takes in this application. Remember we have an MVC front-end that gets data from a data access layer. If the MVC part fits in Bob's "Interfaces adapters", and the domain models of the data layer fit in Bob's "Entities" layer, then what do I call the use case classes that implement application logic? I am tempted to just call them <UseCase>Models and put them in the MVC project, but according to Bob
The models are likely just data structures that are passed from the controllers to the use cases, and then back from the use cases to the presenters and views.
so that means my model objects should be "dumb" (like a simple Map. ModelMap in Spring) and it is then the responsibility of the controller to put data from the Use Case class into this Map-structure.
So again, what form does my Use Case-classes take? How about <UseCase>Interactor?
But in conclusion I realize that the MVC-MV-thing is over-engineering (or simply incorrect) - as "mikalai" indicates below this essentially just a two-layer applcation in its current form; a data access layer and a front-end MVC layer. Simple as that.
Whoa that was a lot. And I think you have mostly translated Uncle Bob's jargon over to your Spring Java app.
Since architecture is mostly opinion and since your question is sort of asking for one...
There are many different styles of architecture and ... most are overrated. Because most are the same thing: higher cohesion and looser coupling through indirection and abstraction.
What matters MOST (IMHO) are the dependencies. Making lots of small projects as opposed to one giant monolithic project is the best way to get "clean" architecture.
Your most important technology for clean architecture will not be "Spring MVC" technology or "Freemarker" templating language, or another Dr. Dobb's article with diagrams of boxes, hexagons and various other abstract polygons.
Focus on your build and dependency management technology. It is because this technology will enforce your architecture rules.
Also if your code is hard to test.. you probably have bad architecture.
Focus on making your code easy to test and write lots of tests.
If you do that it will be easy to change your code with out worry ... so much you could even change your architecture :)
Beware of focusing too much an bull#%$## architecture rules. Seriously: if your code is easy to test, easy to change, easy to understand and performs wells then you have a good architecture. There is no 6 weeks to 6 pack abs article to do this (sorry Uncle Bob). It takes experience and time... there is no magic bullet plan.
So here my own "clean" architecture... I mean guidelines:
Make many small projects
Use dependency management (ie Maven, Gradle)
Refactor constantly
Understand and use some sort of dependency injection (Spring)
Write unit tests
Understand cross cutting concerns (ie when you need AspectJ, metaprogramming, etc..)
My solution
So it turns out that implementing Bob's "Clean Architecture" in Java/Spring MVC is borderline non-trivial and requires more architectural facets than I originally had included.
And I could actually not find any example of implementations online.
Evidently my architecture was missing a separate module for the "Use Case"-layer as this logic should not live in the Spring MVC Web module (and not be called "*ViewModel"). The Web/MVC module is simply a detail of the application, and the application logic should be completely separated from it, and separately testable.
This new "Use Case"-module now contains *Interactor-classes which get data from the domain module (entities). Moreover, "Request/Response Objects" are needed to facilitate the communication between the MVC/Web-module and the Use Case module.
My dependency chain now looks like this:
Spring MVC module -> Use Case module -> Domain module
where every arrow (dependency) takes form as a Boundary, meaning an interface is defined in the module to the right of the arrow that is implemented where required and injected where needed (Inversion of Control).
Here are the interfaces I ended up with (per Use Case):
I<UseCase>Request - implemented in the MVC module, instantiated in the Controller
I<UseCase>Response - implemented in the Use Case module, instantiated in the Interactor
I<UseCase>Interactor - implemented in the UseCase module, injected in the Controller
I<UseCase>Consumer - implemented in the Domain module, injected in the Interactor
How it works?
The Controller takes parameters from the HTTP request and packs it in a RequestModel which it passes down to the Interactor. The Interactor fetches the data it needs from the domain module *Consumer and imposes it's application specific logic on it, then puts it in a ResponseModel and sends it back up to the Controller. The Controller then finally simply puts this (now GUI-friendly) simple data in a Map object and forwards it to the FreeMarker template which then uses this data directly and renders the HTML.
A Presenter could get involved in that last part there, making this an implementation of the Model-View-Presenter pattern, but I'm leaving that for now.
My conclusion
I ended up with more files than what is necessary this early in development, strictly speaking. However as the complexity and size of the application grows, I am confident that this structure keeps it easy for us to maintain low coupling and high cohesion. Also, the Web-module is now easily replaceable - it just delivers requests to the use-case module and receives response-objects. Moreover, each layer of the application (domain logic, application logic, and GUI logic) is separately testable, with only the View-part requiring a webserver in order to be tested.
Thanks for all advice and pointers I received here. And please comment on my solution - I don't claim that it is perfect.
Because of this, we do not have "entities" in the traditional sense
(with Ids), but a data-centric approach making this layer a data
access layer, presented to the rest of the application by the
Consumer-module.
Something seems odd to me in that part. Why couldn't your entities have ID's even if you get them from web services ?
In the Clean Architecture approach, the Entities layer is precisely not a data access layer. Data access should be a detail in your architecture, not a central concern. As you said yourself, Entities contain domain-specific business rules. Business rules, or behavior, is very different from the way you fetch your data.
Entities is where all the domain logic happens, not where you get your data from. According to Clean Architecture, you get your persisted or external data from Gateways.
One solution I've found to this problem is the use a variant of the
"MVVM-pattern" that I choose to call MVC-VM. See below for an
explanation. The "VM"-part of this lives in this Use Case-layer,
represented by *ViewModel-classes that encapsulate this Use
Case-specific logic.
ViewModel clearly refers to a View, which is a presentation artifact -another detail. Use cases/Interactors should be devoid of such details. Instead, Interactors should send and receive delivery mechanism-agnostic data structures (RequestModels and ResponseModels) through Boundaries.
I understand that this is a custom pattern of yours and doesn't involve a reference to a presentation framework, but the word "View" is just misleading.

Looking for design patterns to isolate framework layers from each other

I'm wondering if anyone has any experience in "isolating" framework objects from each other (Spring, Hibernate, Struts). I'm beginning to see design "problems" where an object from one framework gets used in another object from a different framework. My fear is we're creating tightly coupled objects.
For instance, I have an application where we have a DynaActionForm with several attributes...one of which is a POJO generated by the Hibernate Tools. This POJO gets used everywhere...the JSP populates data to it, the Struts Action sends it down to a Service Layer, the DAO will persist it...ack!
Now, imagine that someone decides to do a little refactoring on that POJO...so that means the JSP, Action, Service, DAO all needs to be updated...which is kind of painful...There has got to be a better way?!
There's a book called Core J2EE Patterns: Best Practices and Design Strategies (2nd Edition)...is this worth a look? I don't believe it touches on any specific frameworks, but it looks like it might give some insight on how to properly layer the application...
Thanks!
For instance, I have an application where we have a DynaActionForm with several attributes...one of which is a POJO generated by the Hibernate Tools. This POJO gets used everywhere...the JSP populates data to it, the Struts Action sends it down to a Service Layer, the DAO will persist it...ack!
To me, there is nothing wrong with having Domain Objects as a "transveral" layer in a web application (after all, you want their state to go from the database to the UI and I don't see the need to map them into intermediate structures):
Now, imagine that someone decides to do a little refactoring on that POJO...so that means the JSP, Action, Service, DAO all needs to be updated...which is kind of painful...There has got to be a better way?!
Sure, you could read "Beans" from the database at the DAO layer level, map them into "Domain Objects" at the service layer and map the Domain Objects into "Value Objects" for the presentation layer and you would have very low coupling. But then you'll realize that:
Adding a column in a database usually means adding some information on the view and vice-versa.
Duplication of objects and mappings are extremely painful to do and to maintain.
And you'll forget this idea.
There's a book called Core J2EE Patterns: Best Practices and Design Strategies (2nd Edition)...is this worth a look? I don't believe it touches on any specific frameworks, but it looks like it might give some insight on how to properly layer the application...
This book was a "showcase" of how to implement (over engineered) applications using the whole J2EE stack (with EJB 2.x) and has somehow always been considered as too complicated (too much patterns). On top of that, it is today clearly outdated. So it is interesting but must be taken with a giant grain of salt.
In other words, I wouldn't recommend that book (at least certainly not as state of the art). Instead, have a look at Real World Java EE Patterns - Rethinking Best Practices (see Chapter 3 - Mapping of the Core J2EE patterns into Java EE) and/or the Spring literature if you are not using Java EE.
First, avoid Struts 1. Having to extend a framework class (like DynaActionForm) is one of the reasons this framework is no longer a good choice.
You don't use spring classes in the usual scenarios. Spring is non-invasive - it just wires your objects. You depend on it only if using some interfaces like ApplicationContextAware, or if you are using the hibernate or jdbc extensions. Using these extensions together with hibernate/jdbc completely fine and it is not an undesired coupling.
Update: If you are forced to work with Struts 1 (honestly, try negotiating for Struts 2, Struts 1 is obsolete!), the usual way to go was to create a copy of the Form class, that contained the exact same fields, but did not extend the framework class. There would be a factory method that takes the form class and returns the simple POJO. This is duplication of code, but I've seen it in practice and is not that bad (compared to the use of Struts 1 :) )
I think your problem is not so big as it seems.
Let's imagine, what can you really change in your POJO:
1) name of its class: any IDE with refactoring support will automatically make all necessary changes for you
2) add some field/method: it almost always means adding new functionality what is always should be done manually and carefully. It usually cause to some changes in your service layer, very seldom in DAO, and usually in your view (jsp).
3) change methods implementation: with good design this should cause any changes in other classes.
That's all, imho.
Make a decision about technology for implementing busyness-logic (EJB or Spring) and use its facilities of dependency injection. Using DI will make different parts of your program communicate to each other through interfaces. It should be enough for reaching necessary (small enough) level of coupling.
It's always nice to keep things clear if you can and separate the layers etc. But don't go overboard. I've seen systems where the developers were so intent on strictly adhering to their adopted patterns and practices that they ended up with a system worse than the imaginary one they were trying to avoid.
The art of good design is understanding the good practices and patterns, knowing when and how to apply them, but also knowing when it's appropriate to break or ignore them.
So take a good look at how you can achieve what you are after, read up on the patterns. Then do a trial on a separate proof of concept or a small part of your system to see your ideas in practice. My experience is that only once you actually put some code in place, do you really see the pros and cons of the idea. Once you have done that, you will be able to make an informed decision about what you will or will not introduce.
Finally, it's possible to build a system which does handle all the issues you are concerned about, but be pragmatic - is each goal you are attempting to reach worth the extra code and APIs you will have to introduce to reach it.
I'd say that Core J2EE Patterns: Best Practices and Design Strategies (2nd Edition) addresses EJB 2.0 concerns, some of which would be considered anti-patterns today. Knowledge is never wasted, but I wouldn't make this my first choice.
The problem is that it's impossible to decouple all the layers. Refactoring the POJO means modifying the problem you're solving, so all the layers DO have to be modified. There's no way around that.
Pure decoupling of layers that have no knowledge of each other requires a lot of duplication, translation, and mapping to occur. Don't fall for the idea that loose coupling means this work goes away.
One thing you can do is have a service layer that's expressed in terms of XML requests and responses. It forces you to map the XML to objects on the service side, but it does decouple the UI from the rest.

Categories