I was reading a topic about good practices on web development with Java and found that it is a bad practice to call the DAO from a Servlet. The topic itself did not explained why this is a bad practice, although it clearly explains that, following the best practices, we need a intermediate class (eg.: a service class) to call the DAO.
Why is this a bad practice? Is there any theorical and / or technical explanation to this?
The answer is for the sake of usability.
DAOs resolve access to database objects.
Servlets must be used merely as a facade to handle remote requests and responses (typically HTTP).
Servlets are aimed to do the parsing/formatting of parameters; but they must not know anything about business logic.
So, an intermediate level of business logic classes is necessary between servlets and DAOs. Classes from this level must know the business rules, the database schema and how to use it. This business logic must not be coupled to any deployment schema, so it can be used (and reused) from a number of facades:
servlets/jsps,
swing guis,
spring controllers,
Ant tasks,
etc.
Related
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.
I'm setting up a Spring 3/Hibernate 3.6 application architecture for the first time and have all of the parts configured but need more information about the proper architecture design for a business layer. Please provide advice or links to resources that will suggest the appropriate setup for a separate business layer between my controllers and DAOs. Are there any suggested technologies for business objects or are POJOs normally used? Is the application simply divided with a separate folder, on the same level as my controllers, for business objects?
It depends on the size of your application, what your business objects do and how they depend on each other.
Typically the business objects will reside in one or more folders/packages depending on
functionality, and
their inter-dependence on each other
POJOs will normally do the job specially when you have Spring to take care of the transactionality and other cross cutting concerns.
I have also seen designs of very large applications where the services layer and DAOs are separated out into different applications for more loose coupling. So it really depends on various factors how you lay out the application structure.
Use the business layer to annotate & define your transaction contexts (Transaction Control).
You can package it as per you functional requirements. No set rule.
You can use simple java objects as long as you clearly separate your concerns.
Ensure that you do not use hibernate/db specific APIs in your business/service objects.
Use annotations on your POJOs to define relationships/mappings.
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.
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.
Guys, I HAVE tried reading tons of stuff about EJB. And I don't get it. It seems that most of the authors have a superficial knowledge on it. They basically say it's the business-logic 'stuff'. They don't show it how it interacts with the AppServer and so on, what it does, how, and why?
It is a huge question, but not that huge. It is not like asking what is physics. You basically run your business code inside container which is handling all the connections, lookup, transactions etc. There are alternatives to ejb, e.g. spring.
The question is huge indeed. EJBs in a general sense try to enforce a design pattern that encapsulates all of your reusable code or "business logic" into a specific tier in your architecture. By doing this you can reuse this code for your web/presentation layer and web services for example. EJBs provide a way of persisting your data to a DB.
The trend in java development now a days is POJO driven architectures that leverage dependency injection. Spring is a popular tool to facilitate this design pattern and I would encourage you to explore this instead of EJB.
an enterprise bean is a server-side component that
encapsulates the business logic of an application. The business logic is the code that fulfills the
purpose of the application. In an inventory control application, for example, the enterprise
beans might implement the business logic in methods called checkInventoryLevel and
orderProduct. By invoking these methods, clients can access the inventory services provided
by the application.