Complete separation of client data from the business model?
Do current J2EE best practices provide for complete separation of client data from the business model? Typically, any significant change to data used at or by the client will result in changes to the data model and vise versa. This necessitates changing all of the logic and beans that touch that field or serve the client. If you have separated the business logic as is recommended, then you have those classes to change too.
Take for example it is needed to change a client field from text to numeric, then this change will affect all clients, POJO抯, and DataModel components that use that field.
Is there any pattern or framework that provides complete separation of client data from the model? Or would this have to be custom-made. For example, Hibernate keeps a description of data in an XML file. The XML file is used to create the table, as well as create the data access Java object and SQL. Is there anything that carries this one step further and creates an HTML form for example?
(I am new to this forum - did a quick search but didn't see any similar post on this specific topic)
The Java EE References Architecture consists of three tiers: Presentation, Business, and Integration. Each tier contains the application/code for handling a specific portion of the entire application.
The key separation is between GUI code and business code. The goal is to maintian low coupling between the tiers so that the application can easily support extensibility and manageability. There is no call for the separate of data. Data must flow up and down the tiers in the best way possible. How that is accomplished depends on the system architecture and technical design of the application. Changes to data format do not neccessarily mandate a change to logic.
In most cases, data that comes from the Presentation tier comes down in a text/string format and typically data is sent from the Business tier in the same fomat.
According to the application's business rules, text/string formats are usually converted in the code residing in the Business tier.
The business model of an application needs the data from the user. There should be no such thing as a separation of user data and the model. This is no such design pattern or framework whose purpose in to separate user data from the business model, that I am aware of.
Maybe I am reading too much into the loosely coupled concept. Let's say you are part of a project light on "Big Design Up Front" in favor of frequent releases. You make a user interface for maintaining data. After the first release, the user community wants changes that result in changes to the database. Your user interface no longer works. Is there any suggestion in the developers community that this kind of change will not affect the presentation, middle, and data object code?
> Do current J2EE best practices provide for complete
> separation of client data from the business model?
What does this mean?
If you write a class with complete separation, that means that no other classes use it. What good is that?
It's an ideal that's worthless, IMO.
> Typically, any significant change to data used at or
> by the client will result in changes to the data
> model and vise versa. This necessitates changing all
> of the logic and beans that touch that field or
> serve the client. If you have separated the business
> logic as is recommended, then you have those classes
> to change too.
So how are they useful if they know nothing about each other?
If you add a column to a database, and you'd like that column to be used by clients, how can you avoid changing the form and intervening objects?
> Take for example it is needed to change a client
> field from text to numeric, then this change will
> affect all clients, POJO抯, and DataModel components
> that use that field.
What else do you propose to do?
> Is there any pattern or framework that provides
> complete separation of client data from the model?
You can minimize the changes by having client/server. Just two changes then: add or change a column in the database, add or change the item in your big, fat client. Just two!
But now you've gone back to the 1980's and early 90's and killed all the benefits that layering and multi-tiered apps have given you.
> Or would this have to be custom-made. For example,
> Hibernate keeps a description of data in an XML
> file. The XML file is used to create the table, as
> well as create the data access Java object and SQL.
> Is there anything that carries this one step
> further and creates an HTML form for example?
There are code generators to help with all these things. Have a look at Matt Raible's AppFuse, for example.
But I believe that even Matt Raible would agree that AppFuse is intended to give some lift by generating boiler plate, not by providing "push button application" without any thought or work.
What you're proposing is "convention over code", which is a lot of the lift that Ruby gets for CRUD apps over the web. It helps, but I personally don't believe that there's any free lunch in life.
%
> Typically, any significant change to data used at or
> by the client will result in changes to the data
> model and vise versa. This necessitates changing all
> of the logic and beans that touch that field or
> serve the client. If you have separated the business
> logic as is recommended, then you have those classes
> to change too.
>
> Take for example it is needed to change a client
> field from text to numeric, then this change will
> affect all clients, POJO抯, and DataModel components
> that use that field.
That maybe will change the signature of a few methods, but not necessarily the "logic" (take user input, if it is "valid" update the model, persist the data, update the view,...).
Even the signature change can be avoided if you create custom data types to hold sensitive fields (e.g. an Address class instead of a couple of Strings, an ID class instead of an int field,...). That may be an overkill, so balance abstraction with the likeliness of change.
That leaves with only a few spots subject to change:
* persistence (generally externalized in metadata)
* UI (but if you originally did not include the "country" notion in your addresses, and now want to expose it, you cannot avoid revamping the UI).
* data-specific (such as, validate the new country code field), most of which is likely to end in the data type class (or a related utility class), so not really scattered throughout all the code.
> Maybe I am reading too much into the loosely coupled
> concept. Let's say you are part of a project light on
> "Big Design Up Front" in favor of frequent releases.
> You make a user interface for maintaining data.
> After the first release, the user community wants
> changes that result in changes to the database. Your
> user interface no longer works. Is there any
> suggestion in the developers community that this
> kind of change will not affect the presentation,
> middle, and data object code?
Let's see. You have a GUI for maintaining data.
Now. You released the application and it works fine.
Now, the user community wants changes that result in changes to the database.
Here is a point. It all depends upon the business requirements and the type of data and the source of the data. You could have possibly designed the application so that GUI changes would not effect the database. If the user community wants significant data changes and your database design was not that fancy, then you have to do more work for the second release.
Database design is a key issue here. There are many type of ways that a database can be designed. Using meta-data tables, it is possible to add and remove data from databases via configuration files. Here, the application is designed so that nothing has to be recoded.
If the application has high-levels of coupling and was designed in a bad fashion, then changes like you mention will require work on all tiers. If the application was designed with low coupling then it should sustain mild revisions pretty good.
There is always some work somewhere, effective developers typically desgin the app so that they will not have to do much for minor changes in future releases. And they typically push on the GUI stuff for things to be changed. Presentation tier developers are usually the youngest and least experienced and they need more work :o)
>
> Database design is a key issue here. There are many
> type of ways that a database can be designed. Using
> meta-data tables, it is possible to add and remove
> data from databases via configuration files. Here,
> the application is designed so that nothing has to be
> recoded.
And one should only do that because there are defined business requirements that drive it and not because the programmer doesn't want to type three extra lines for a future version of the code.
> There are code generators to help with all these> things. Have a look at Matt Raible's AppFuse, for> example.Thanks, Duffymo. AppFuse looks intriguing. If it works, I'll become a Matt Raible fan.
> If the user community wants significant
> data changes and your database design was not that
> fancy, then you have to do more work for the second
> release. Database design is a key issue here. There are many
> type of ways that a database can be designed. Using
> meta-data tables, it is possible to add and remove
> data from databases via configuration files. Here,
> the application is designed so that nothing has to be
> recoded.
GhostRadioThree: Most production systems I work on have a traditional RDBMS created by the DBA's. If the requirements change, they usually add/remove columns or change data types. So this isn't really in my control.
> You could have possibly designed the
> application so that GUI changes would not effect the
> database. If the application has high-levels of coupling and
> was designed in a bad fashion, then changes like you
> mention will require work on all tiers. If the
> application was designed with low coupling then it
> should sustain mild revisions pretty good.
Right. The only way I can think to achieve this is to make a mid-tier object, kind of like a Business Facade, or a Transfer Object. I try to make it so that an "Address Record" is as abstract as possible. So the client can call a method: getApartmentNumber( ). Later, if the Apt. number field is nixed from the database because it comes from somewhere else, I can feed that to the mid-tier bject so it can still produce getApartmentNumber( ). This would also work if the client decided to treat the Apt. number as a number instead of a String. The TransferObject would handle the conversion (even though, at the outset it seems like the mid-tier object duplicates work done by the DAO with all the getters and setters). However, the mid-tier object won't help if fields are added to the client and the database. This forces updating, re-testing, and hopefully not breaking the mid and model objects. I'm not trying to beat this to death - if this is the best way to do it I'm fine with that.
> GhostRadioThree: Most production systems I work on
> have a traditional RDBMS created by the DBA's. If
> the requirements change, they usually add/remove
> columns or change data types. So this isn't really in
> my control.
A relational data base management system (RDBMS) and a relational database are two different but related things. Oracle and MS SQL Server are examples of a RDBMS. The relational databases that one creates for business applications are managed by the RDBMS.
You can try to influence a better database design, so that the database can handle simple things like add/remove columns and type changes.
> would handle the conversion (even though, at the
> outset it seems like the mid-tier object duplicates
> work done by the DAO with all the getters and
> setters).
Use the same class for the Transfer Object and the DAO.
>
> You can try to influence a better database design, so
> that the database can handle simple things like
> add/remove columns and type changes.
>
Did you mean to say database in the second part of that or code?
>
> Use the same class for the Transfer Object and the
> DAO.
I disagree with that particularly if it really is an attempt to combine the two rather than just dispense with the DTO.