If I have a JSF backing bean that imports a domain object and uses EL to populate instance variables, is this a violation of separation of concerns and do I need to wait until the business logic or later to import the domain object
I'm not sure how you're managing to warp EL to affect server-side properties, but yes, if you did you, you'd be fracturing the MVC Separation of Concerns Big Time.
There are several reasons why the View should not attempt to do logic. One of the biggest is that the whole point of Separation of Concerns is to localize functionality. Everything that does one thing is in one place. Otherwise it becomes a "treasure hunt" every time you want to do anything. Is the logic here? Or there? Or is is split between here, there, and everywhere?
Of course, some people don't care. To which I generally respond. Well, if adopting the common discipline isn't good enough for you, consider that debugging complex EL is a right royal pain in the...
An IDE is no substitute for an Intelligent Developer.
Joined: May 11, 2011
If I have a JSF registration form containing 20 fields and an associated backing bean, does separation of concerns dictate that in my backing bean, I define 20 non-object oriented variables that are populated from the web page using EL and then passing those to the business layer which would then pass them to a constructor in the java entity.
I think there's some fundamental confusion here. I'm not sure what "non-object-oriented" variables is supposed to mean, but the backing bean (Model) normally serves as the staging area between collecting (or displaying) data and the business logic. JSF adheres to the batch-oriented concepts first laid down in HTTP long before Java got into the act, so it's not like the GUI controls drill straight down to business functions. They're submitted from a FORM as a unit, and JSF won't even update the Model unless each and every item on that form is valid, much less fire off any logic.
The EL in the value= attributes of JSF controls does not "update" anything. It declares the mapping between the View template and the Model, by declaring what property of what Model (backing bean) are associated with each control. The actual validation and data transfer to/from the Model is done by JSF's built-in Controllers, not by the EL.
Joined: May 11, 2011
Thank you that was very helpful. I do not know if I am mixing templates; but it seems to me like most texts talk about Presentation <--> Business Logic <--> Persistence. I was thinking that the Persistence layer and the model were pretty much one in the same. Your description makes it sound more like Backing Bean <---> Model <---> Business Logic. I guess I am being way to linear here. I guess it could be that the backing bean updates the model (after verification) and the backing bean calls action methods in the business logic which access the model for data and then any changes made in the model are sent back to the presentation layer for display. If I am getting closer, where does a DAO fit in if at all? Is it part of the business logic used to access the model? Thanks again. Not to make you write a book, but does domain driven architecture then focus on whether a given bit of logic is more entity related or business related? Thanks again again.
That's the "3-tier" webapp architecture. The 3 tiers are (IIRC), presentation, business logic and persistence. There's also a 2-tier model where an ActiveX control (or more rarely a java applet) in the client talks directly to the backend database. 2-tier apps are how the SQL Slammer managed to wreak such havoc on the Internet several years back.
3-tier architecture is different from Model/View/Controller (MVC). MVC predates the Internet and was a hallmark of programming in the Smalltalk language. Its separation of concerns made it easier to design and implement complex GUI applications
JSF is one of the purest implementations of MVC that you can find for web use. It's not "full" MVC because no webapp on any platform or in any language can asynchronously post updates to the View when the Model changes - instead they get done as part of the next client request/response cycle. However, it's close enough, especially with help from AJAX.
I actually tend to have a lot more than 3 tiers these days.
On the server side, I have, starting from the outer tier:
1. JSF at the (including extensions, such as PrettyFaces and RichFaces)
2. View templates and Backing Beans (the Model)
3. Business logic (for very simple logic, this may be part of the action processors in the backing beans).
4. Persistent Business Logic. A lot of my apps work with sets of interrelated ORM data sets that need to be manipulated within a single database transaction. They go here.
5. Simple Persistence. These are the DAOs, which access only a single table. They are invoked from the persistent business logic and may contain "finder" methods. In other words, the actual database queries are done here, as are the fetches and updates of the anchor tables for Tier-4 operations.
6. Object Relational Model. These are the Entity Beans.
7. Persistence mechanism. The low-level driver classes for persistence. Usually I'm using JPA and Spring, and Spring manufactures these and plugs them into the DAOs.
Although that's a lot of layers, each layer is fairly simple and has limited Concerns, which are kept Separated, so yes, that's SoC in action. I could do with fewer and sometimes do, but I prefer that all database-related operations be done at Tier 4 and lower so that Tier 3 and up are working with detached data objects. A lot of people don't do this, but I personally feel its safer and cleaner, one you get used to the extra gate-keeping.
Joined: May 11, 2011
Thanks for a great explanation. How do you define your model in the backing bean level 2 without using the entity beans in level 6?
Michael Brooks wrote:Thanks for a great explanation. How do you define your model in the backing bean level 2 without using the entity beans in level 6?
One of the advantages of EJB3/JPA is that the Entity objects can serve as their own DTOs, in effect. An since they are data containers rather than logic objects, they can safely be passed up and down the tiers, even though I've assigned them a level near the bottom of the stack. As I mentioned, once they leave the Persistent Business level, I detach them from the persistency mechanism and don't re-attach (merge) them until another request makes the trip down the stack.
Entity beans make lousy JSF backing beans, since JSF backing beans are statically defined. So usually the backing bean serves either as a façade or aggregator for the Entity beans rather than attempting to force the Data Model to double as the GUI Model. The backing bean's primary purpose, as I said earlier, is as a staging area.
Joined: May 11, 2011
Do you know where there is a documentend example web app of at least some of these layers that includes package names.
There's no real standard. I don't even have a 100% cast-iron standard for my own projects. And, for the record, I have a very poor opinion of shops where the standards are cast-iron, anyway, since that converts them from productivity aids into productivity hobbles. Flexible standards are good. Inflexible ones aren't. And good developers know when to flex and when not to flex. And monkey-programmers will produce monkey-code no matter how many standards you subject them to.
However, here's a typical set of naming standard for me. The project root will be something like "com.mousetech.projectxxx".
Under it, I typically have the backing beans in a "backing" package, with the bean names in the form "xxxxBean".
For persistent business services, the package is something like "persistent.services.xxxxService".
For DAOs, that would be "persistent.dao.xxxxxDAO".
For ORM models, "persistent.model.xxxxx".
Complex apps often have me dividing into sub-packages based either on function or workflow. So I might have a "backing.reporting" package or a "backing.booking" package. Whatever organizes things most cleanly for the project at hand. Remember I did say I don't like cast-iron standards! So "com.mousetech.accounteditor.backing.user.UserInfoBean" would be a typical classname.
Note that I prefer to code the domain into the classname even though the package name indicates it already. That's because I've found that my IDE is more helpful to me when the classname is unique within the project.