Forum Controls
Spotlight Features

The Rich Engineering Heritage Behind Dependency Injection

Andrew McVeigh takes us on a tour of the rich heritage behind dependency injection, what it represents, and tells us why its here to stay.

NetBeans 6: Matisse Updates

NetBeans 6 delivers great updates to the Matisse GUI builder. Spend a few minutes with Roman Strobl and get an expert briefing on what's new and what has changed.

Introduction to Groovy Part 3

In this, the third and final installation of Andres' Introduction to Groovy series, you learn about how Groovy handles variable numbers of arguments, named parameters, currying, and more about Groovy operators. Including, some new operators.

Easier Custom Components with Swing Fuse

Swing Fuse (actually just Fuse), is a framework designed to make it easier to create your own custom desktop components. In this article, Daniel Spiewak shows you how to get started and provides sample source code you can download.

Benchmark Analysis: Guice vs Spring

Willam Louth shows how he uses JXInsight Probes to investigate probable performance issues with code bases that he is not familiar with. He also highlights possible pitfalls in creating a benchmark, as well as in the analysis of results.
Replies: 20 - Pages: 2   [ 1 2 | Next ]
Threads: [ Previous | Next ]
  Click to reply to this thread Reply

The State of "The Design"

At 8:22 AM on Mar 27, 2006, Matthew Schmidt wrote:

The Java platform has celebrated its 11th anniversary, the first EJB spec was released 7 years ago and Spring just celebrated the 3th anniversary of the 1.0 release. Steven Devijver takes a look at the state of application design and some its pitfalls.

Read Steven's whole article now!
1 . At 2:32 PM on Mar 27, 2006, Ürgo Ringo wrote:
  Click to reply to this thread Reply

Re: The State of "The Design"

I agree completely that good object should contain both data and behavior.

However it gets a bit confusing when UI and persistence are added to the mix. For example if using Javabeans in relatively simple JSP page it is very appealing to use the same bean also as DTO through all layers. Unless some completely different approach is used for UI how else could data entered by the user get to the business layer? Once we are using it to transfer stuff from presentation to business layer it seems like a very small step to use it also as input for persistence.


Rgrds,
Yrgo
2 . At 2:50 PM on Mar 27, 2006, Gonzalo Díaz wrote:
  Click to reply to this thread Reply

Re: The State of "The Design"

Doesn't Spring command object double up ad data transfer object?
What is the damage in using DTO, again?

Gonzalo
3 . At 4:44 AM on Mar 28, 2006, Erwin Vervaet wrote:
  Click to reply to this thread Reply

Re: The State of "The Design"

Steven,

I just read your "The State of "The Design"" article on Javalobby.

I fully agree with many of the arguments you make. Consistency and
simplicity should indeed be among the top priorities of any software
engineer.

However, I think the following statement regarding DTOs deserves a bit more
nuance:

"However, as I write this State of the Design, I feel developers are still
negatively influenced by the EJB specifications, although they no longer
deploy their applications in EJB containers. One notable example of this is
the survival of the Data Transfer Object (DTO) Design Pattern in modern
application while there is absolutely no need anymore to use it."

The reactions here in the forum are also on this topic. A few
years ago, the "DTOs are evil" plea was a popular one. I'm a bit of an
object purist so I partially backed this up: DTOs are not true objects.
However, experience has lead me to believe that DTOs do have a place in a
well designed OO application. It's a useful pattern that, like you point
out, should be used correctly!

Let's take a simple example: say you have a bidirectional parent-child
relation in your domain model between a Company and it's parent Company.
Let's say you've mapped this to your RDBMS using some ORM tool, e.g.
Hibernate. (So at the persistence side of things there are not DTOs: your
domain model is directly persisted.) Now we have a simple use-case where we
need a screen to edit a company's details: The name, the CEO, the list of
child companies, .... Implementing this using SpringMVC and trying to do
direct data binding onto the domain objects will prove very frustrating
indeed! The fact that your domain model objects have side effects in their
methods (e.g. changing the parent of a Company affects 3 objects: the child
itself, the old parent and the new parent) will basically rule out any
direct binding onto the domain object itself. So what are you going to do?
The anwser: create a DTO that captures the data input by the user and have
some service layer (or controller or whatever) apply that to your domain
layer.

IMHO there are many such cases where DTOs provide value. As I see it now,
DTOs are not all bad, certainly not when they're used correctly:
- They don't directly mirror any particular database table or domain
object: they mirror a particular use-case and their responsability is
capturing the data related to that use-case when it travels into the system.
So I'm cerainly NOT saying you should replace your rich domain model with
DTOs and transaction scripts.!
- Like others have argued, DTOs insulate your domain model from the UI
(or other 'interfaces', e.g. remote): you're free to refactor your domain
model without impact on those interfaces.
- DTOs can offer a lot of consistency in some areas (e.g. web data
binding): their a simple solution that works in all cases: both the simple
and complex ones. This is usefull if you want to fully standardise how
use-cases are implemented in a project. So in this case DTOs improve
consistency!
- Some projects, like WebWork and Struts incurage the developer to have
DTOs, e.g. WW actions that hold the data coming into the app from the HTML
form. For straightforward cases this can be overkill, but there is the
consistency argument to consider (see previous point).

You could do stuff like 'data holder maps' to do away with the DTOs. I'm not
a big fan of this since DTOs are simple, easy to understand, easy to
refactor, clear to all developers and the maintenance cost is as a result
relatively low.

So at this moment I consider DTOs a 'necessary evil'. Maybe I've missed
something and there are better ways to do things. Feel free to enlighten me
:)
4 . At 6:14 AM on Mar 28, 2006, Steven Devijver wrote:
  Click to reply to this thread Reply

Re: The State of "The Design"

Hey Yrgo,

First of all, in this article I especially target the use of Data Transfer Objects in the business logic of applications, something I often encounter in applications, also in 2006.

The main reason why they are used is exactly like you say, they are used in the persistence and user interface anyway , so why not use them everywhere?

I will discuss the use of Data Transfer Objects in the user interface and persistence below.

USER INTERFACE
============

The use of Data Transfer Objects in the user interface can be avoided. First of all, it's a matter of designing your business logic. I won't reiterate the points made in the Domain-Driven Design book here and I suggest you pick up a copy of this book if you haven't already.

Tapestry, Wicket and recently Wedge prove it's possible to bind to method arguments instead of using Data Transfer Objects. Method arguments do have some limitations as they don't deal very well with optional parameters (varargs don't cut it either).

There are two alternatives that are both 'cutting edge':

1) using a form backing object but binding to private fields

2) using an automated adapter to bind method arguments.

The first solution is better than Data Transfer Objects since almost all of them I've seen indirectly bind private fields anyway without checks. When directly binding to private fields you gain the advantage of not adding accessors (setter methods) to your classes and keep a clean design.

The disadvantages are that you still have to know about the internals of the class - troublesome when you don't have access to the code but also in cases where you do - and it also complicates user interface validation.

The second alternative is an automated adapter that binds method arguments. I prefer to call this adapter the Dozer, I'm not sure why, maybe because it pounds through layers and walls.

Consider this method on PlayerManager:

Player addPlayer(String firstName, String lastName, Date dateOfBirth, String clubName) throws PlayerAlreadyExistsException;

In a Spring MVC controller you can use the Dozer to invoke this method and bind method arguments:

ServletDozer dozer = new ServletDozer(playerManager, "addPlayer(firstName, lastName, dateYMD(birthYear, birthMonth, birthDay), clubName or null)");
Player player = (Player)dozer.invoke(request);

Obviously you can inject the dozer instance here. The Dozer will try to figure out what method to invoke and how to convert the parameters by using PropertyEditors. The Dozer is a class I'm working on and it probably will take some more work and testing until it's fully ready.

All this to say that no, Data Transfer Objects are not required in the user interface. This doens't mean it's bad to use them, as long as it makes sense to you. This is important: does it make sense to you? I encourage you to dare question frameworks and well-documented and popular usage patterns. If you don't understand it it may you not make sense.

Whatever you do I would not pass these user interface Data Transfer Objects in your business logic because this will negatively affect your design just because you use them in the user interface.

PERSISTENCE
=========

Data Transfer Objects and persistence is a whole different story, and before I discuss this in some more detail I want to make a point:

I think we all agree the user interface problem domain and persistence problem domain are very, very different. Then why would you choose to use the same classes in both domains? Will it effectively solve your problem?

At a superficial level the user interface and persistence share a common concern: binding properties/fields on objects. Binding, binding, binding (shouting to audience).

However, while binding is fairly important in MVC it's a marginal concern in persistence, since the problem domain is much bigger.

Many developers think about the database as an aspect of the application, a necessary evil that serves the application because there are few alternatives to consistently store data.

In fact, the database serves a very different purpose than the application.

The application manages/controls/runs business processes.

The database stores the state of business processes.

At any given point the database can tell me the state of an order, however if I want to change the state I have to use the application.

Developers should try do identify what state needs to stored in the database. Draw each business process/use case and put the database at the start (if appropriate) and the end (also if appropriate) of the business process/use case. Try to determine what data is absolutely required in the database. Don't store anything else because it just doesn't make sense. Keep it as simple as possible.

Also do this if you don't have an overview of all the processes or don't fully understand them. Just draw and talk to domain experts to fill in the blanks. (Don't forget to tell them you don't know anything about the problem domain because most of them just assume you do.)

What the domain model should do is provide hooks to *receive* data from the database and *prepare* data to be stored in the database.

The Game class I show in the article is part of a tennis tournament management application and serves to track the course of a tennis game during a match. During the course of the match no data is stored in the database.

It's up to the application (web, Swing, ...) to store the objects safely to protect against data loss from power outage or software errors. Only when the macth (business process) is completed a MatchStatistics object is created that is stored in the database.

This is consistent with the requirements since after a match is completed only a number of statistics are important (set scores, number of aces, number or errors, ...).

This data is presented to the persistence layer through the MatchStatistics object for storage in that database and is also used for diplay on the screen when historical data is requested.



Hope this helps.

Steven
5 . At 6:17 AM on Mar 28, 2006, Steven Devijver wrote:
  Click to reply to this thread Reply

Re: The State of "The Design"

Hey Erwin,

I refer to my previous reply in this forum. I hope you find answers to the points you make.

Steven
6 . At 7:59 AM on Mar 28, 2006, Fredrik Bertilsson wrote:
  Click to reply to this thread Reply

Re: The State of "The Design"

> using a form backing object but binding to private
> fields

Doen't this break encapsulation?

> ServletDozer dozer = new ServletDozer(playerManager,
> "addPlayer(firstName, lastName, dateYMD(birthYear,
> birthMonth, birthDay), clubName or null)");
> Player player = (Player)dozer.invoke(request);

Typing method names and arguments as strings? If you type "adPlayer" instead of "addPlayer" you will get an runtime exception instead of compilation error.


> The application manages/controls/runs business
> processes.
> The database stores the state of business processes.

A database can "control business processes" too. Integrity checking and transaction handling are important features that a database do better than the application. Querying are also a very important feature that a database do much better than the application. Finding information has almost nothing to do with "storing state".

> Try to determine what data is absolutely required in the > database. Don't store anything else because it just
> doesn't make sense.

In many data mining scenarios, calculated and aggregated data should be stored in the database to speed up reports.

Fredrik Bertilsson
http://butler.sourceforge.net
7 . At 8:44 AM on Mar 28, 2006, Steven Devijver wrote:
  Click to reply to this thread Reply

Re: The State of "The Design"

Hey Fredrik,

>
> Doen't this break encapsulation?
>

It does as I mention in the next paragraphs.

> > ServletDozer dozer = new
> ServletDozer(playerManager,
> > "addPlayer(firstName, lastName, dateYMD(birthYear,
>
> > birthMonth, birthDay), clubName or null)");
> > Player player = (Player)dozer.invoke(request);
>
> Typing method names and arguments as strings? If you
> type "adPlayer" instead of "addPlayer" you will get
> an runtime exception instead of compilation error.
>

I'm not sure what your point is but I'll assume you consider this a bad thing. It's up to developers which tools and techniques they use, depending on local politics and believe systems.

However, the compiler is not everything. As I've mentioned the Dozer is an adapter that can be configured externally through composition. Validating the expression happens when the Dozer is constructed so it's perfectly possible to report errors consistenly. There's nothing wrong with this kind of configuration via Strings.

>
> > The application manages/controls/runs business
> > processes.
> > The database stores the state of business
> processes.
>
> A database can "control business processes" too.
> Integrity checking and transaction handling are
> important features that a database do better than the
> application. Querying are also a very important
> feature that a database do much better than the
> application. Finding information has almost nothing
> to do with "storing state".
>

They can but I don't think they should since it's next to impossible to implement this in a consistent way. By design relational databases offer poor integrity check mechanisms and you soon end implementing triggers, stored procedures and views. These can and probably will contain important business logic constraints that now have become invisible for fellow application developers.

Although there may be performance benefits you move away from a unified application design, reducing is to a partial implementation of business processes, loosing it's expressiveness. Furthermore, the normally difficult field of database integration now has become even more difficult, going for the extreme.

Unless database logic is duplicated from application logic which may be a valid use case in some corner cases but is an expensive requirement so should be avoided if possible.

Important checks that have to be performed by relational databases are foreign key constraints, uniqueness constraints, field constraints and the like as it's often the only way to assure valid state in a concurrent environment.

Also, modern persistence tools in Java can perform batch updates to the database at the end of a transaction although this is often not trivial. Some things however should always be done on the database directly, like batch uploads which is much easier and way faster when performed on the database directly using vendor tools.

I disagree transaction management is better done by the database, applications can and should control database transactions for better application semantics and to support expressiveness of the domain model.

I can't produce a quote where I say querying should not happen in the database.

> > Try to determine what data is absolutely required
> in the > database. Don't store anything else because
> it just
> > doesn't make sense.
>
> In many data mining scenarios, calculated and
> aggregated data should be stored in the database to
> speed up reports.

If this is a requirements it's not something that has an important impact on the design on the application. When this kind of data needs to be added (for example: average duration in seconds per rally) it's trivial to add this to the MatchStatistics class. A good application design is very efficient for calculating aggregates.

>
> Fredrik Bertilsson
> http://butler.sourceforge.net

Steven
8 . At 1:41 PM on Mar 28, 2006, Erwin Vervaet wrote:
  Click to reply to this thread Reply

Re: The State of "The Design"

Fredrik already makes some good points especially regarding the use of string literals to invoke methods reflectively. This can be a real pain in the butt if you start refactoring! So there's certainly something wrong with this kind of configuration via strings!


Regarding DTOs in the UI:

> There are two alternatives that are both 'cutting edge':
>
> 1) using a form backing object but binding to private fields

Ugh. IMHO that's worse that DTOs. Also, it suffers from the same problem as point 2.

> 2) using an automated adapter to bind method arguments.

Your 'Dozer' is a nice class, but it won't help in some cases, unless you move the transactional boundary of your system into the Web controller or make the service layer use the Dozer in which case it becomes Servlet API dependent. Both options are not ideal and the KISS solution is the DTO: it's the data transfer contract between your service layer and your interface layer(s).

> All this to say that no, Data Transfer Objects are not required in the user interface.
> This doens't mean it's bad to use them, as long as it makes sense to you.

This already a much more nuanced p.o.v. :)
KISS: use a DTO when it makes sense!

> Whatever you do I would not pass these user interface Data Transfer Objects in your
> business logic because this will negatively affect your design just because you use
> them in the user interface.

True. I mostly see the DTOs as (use-case specific) data transfer contracts between the service layer of an app and it's interface layers. The domain layer of your app should not depend on the DTOs.



I agree that there are very few, if any, use-cases in the persistence area where DTOs still make sense.

Erwin
9 . At 4:14 AM on Mar 29, 2006, Fredrik Bertilsson wrote:
  Click to reply to this thread Reply

Re: The State of "The Design"

> However, the compiler is not everything.

Maybe not, but the compiler is more important than to any cost achieve encapsulation. Encapsulation is impossible to achive in most business applications.

> There's nothing wrong with this kind of configuration
> via Strings.

Configuration is one thing, but typing method calls as strings has several severe flaws as a pointed out before.

> By design relational databases offer poor integrity
> check mechanisms and you soon end implementing
> triggers, stored procedures and views. These can and
> probably will contain important business logic
> constraints that now have become invisible for fellow
> application developers.

Another option is to hire developers that know how to browse a trigger or stored procedures.

> Important checks that have to be performed by relational
> databases are foreign key constraints, uniqueness
> constraints, field constraints and the like as it's
> often the only way to assure valid state in a concurrent
> environment.

Fine that we can agreee upon something. (But some people that care too much about OOAD prefer to skip the use of foreign keys and implement the corresponding logic in the application).

> I disagree transaction management is better done by the
> database, applications can and should control database
> transactions for better application semantics and to
> support expressiveness of the domain model.

The only thing the application should do is to tell the database when the applications starts and when (and how) its ends. The database must do the rest. Otherwise you strongly underuse the database.

> I can't produce a quote where I say querying should not > happen in the database.

You said:
"The application manages/controls/runs business processes.
The database stores the state of business processes. "

Querying is not about "storing". Even if you don't have persistence needs at all, you would probably need queries.
If you claim that the only task for the database is to "store a state", when you are claiming that queries should be done somewhere else. (In fact, in many OO applications, data are fetched from the database in a rather clumsy way and filtered later in the application.)

Fredrik Bertilsson
http://butler.sourceforge.net
10 . At 4:55 AM on Mar 29, 2006, Steven Devijver wrote:
  Click to reply to this thread Reply

Re: The State of "The Design"

Hey Fredrik,

> > However, the compiler is not everything.
>
> Maybe not, but the compiler is more important than to
> any cost achieve encapsulation. Encapsulation is
> impossible to achive in most business applications.

Let me put this in another way: many applications are so badly designed it's impossible to encapsulate. Encapsulation is possible in every application but it doesn't come out of the box. I quote David Birmingham in his excellent book "Sofware Development on a Leash" (2002, Apress, 1893115917):

"Do you think Visual Basic, JavaScript, [Java], or other more recent waves of object language environments will make design and architecture easy? If so, you're in for a bumpy ride. Excellence in design and architecture do not pop out of a box onto a desktop."

Developers and projects that think it's about the compiler and not the design will fail miserably, you can quote me on that. And failing doesn't mean the project is not delivered, it's a measurement of how satisfied users or customers are about the application and how flexible it is to maintain, improve and extend.

Don't forget, if you take the completion of a project as the measurement for success you are ignoring the fact that the first release of a project is just that: the first is a long line of releases to extend the application. I've seen many applications that spawned into production only to be replaced after one year because it's impossible to change and maintain. That's failure for me since a lot of money and time has been wasted, assets that your more successful competitors have used to build a better application.

>
> > There's nothing wrong with this kind of
> configuration
> > via Strings.
>
> Configuration is one thing, but typing method calls
> as strings has several severe flaws as a pointed out
> before.

Please quote/ellaborate on that.

>
> > By design relational databases offer poor integrity
>
> > check mechanisms and you soon end implementing
> > triggers, stored procedures and views. These can
> and
> > probably will contain important business logic
> > constraints that now have become invisible for
> fellow
> > application developers.
>
> Another option is to hire developers that know how to
> browse a trigger or stored procedures.

I think you suffer from the utopian superman and superwoman view on developers. Do you realize how unreadable and obfuscated stored procedure code is? Do you have any idea how unstructured a cascade of triggers is?

Do you actually expect developers to understand such a Gordian knot? I've seen an experienced Oracle developer walk in to analyze the structure of a project that heavily relied on stored procedures. After 30 minutes he told us: "You're putting business logic in your database?! Don't do it!"

Data in a database is a raw representation, even if you use aggregates. It's the virtue of Object Oriented Programming to turn this data into processes and through the use of Design Patterns developers can turn these data structures into an expressive model that *hides* (shouts HIDES to audience) the data and adds behaviour.

As developers it's impossible to successfully work with data without using encapsulation and this is exactly what stored procedures suffer from. Sure, you can encapsulate data structures behind functions but there are no patterns you can exploit. Instead you'll have to repeat yourself all over the place.

>
> > Important checks that have to be performed by
> relational
> > databases are foreign key constraints, uniqueness
> > constraints, field constraints and the like as it's
>
> > often the only way to assure valid state in a
> concurrent
> > environment.
>
> Fine that we can agreee upon something. (But some
> people that care too much about OOAD prefer to skip
> the use of foreign keys and implement the
> corresponding logic in the application).
>
> > I disagree transaction management is better done by
> the
> > database, applications can and should control
> database
> > transactions for better application semantics and
> to
> > support expressiveness of the domain model.
>
> The only thing the application should do is to tell
> the database when the applications starts and when
> (and how) its ends. The database must do the rest.
> Otherwise you strongly underuse the database.

It's ok to underuse a database if it makes sense. Do you always drive to car to its limits? Probably not because it doens't make sense. It's actually advisable to strongly underuse your car if you want to live another day.

What features can applications underuse in databases that make them miss out on real power?

>
> > I can't produce a quote where I say querying should
> not > happen in the database.
>
> You said:
> "The application manages/controls/runs business
> processes.
> The database stores the state of business processes.
> "
>
> Querying is not about "storing". Even if you don't
> have persistence needs at all, you would probably
> need queries.
> If you claim that the only task for the database is
> to "store a state", when you are claiming that
> queries should be done somewhere else. (In fact, in
> many OO applications, data are fetched from the
> database in a rather clumsy way and filtered later in
> the application.)

That's not what I said. You can't assume I expressed the roles of databases and applications in two lines :-)

>
> Fredrik Bertilsson
> http://butler.sourceforge.net

Steven
11 . At 7:39 AM on Mar 29, 2006, Werner Keil wrote:
  Click to reply to this thread Reply

Re: The State of "The Design"

Thanks a lot for your signature!

Not currently able to introduce it in a new architecture, your Butler frameworks looks very interesting.

I had some similar DB Persistance frameworks and other J2EE toolkits (just when J2EE started to be defined 7 years ago ;-) ) put together into a project named OdyssEE (at SF) but I could not get to document it well enough back then to expose it to a broader community.

While some really big players have emerged (especially Hibernate) smaller framework like yours sometimes could be easier to use.
From the API and its "wording" I would especially recommend it if MS technologies or Databases were involved (I guess the "NWIND" sample does not come out of nothing there either ? ;-) )
12 . At 7:49 AM on Mar 29, 2006, Werner Keil wrote:
  Click to reply to this thread Reply

Re: The State of "The Design"

>Developers and projects that think it's about the >compiler and not the design will fail miserably, you >can quote me on that. And failing doesn't mean the >project is not delivered, it's a measurement of how >satisfied users or customers are about the application >and how flexible it is to maintain, improve and extend.

I guess I WILL quote you on that! ;-)

I have seen a few projects fail because the relevant decision makers could not or would not understand real (J2EE) patterns before their nose. In fact between 1998 and '99 (soon after J2EE was presented at JavaOne '98) I proposed a series of technologies and frameworks.
One was even called "Domain Framework" trying to deal with Oracle Databases and their newly introduced JVM inside the DB (8i ff.)

The product manager went for a common "Anti Pattern" (using Entity Beans everywhere including the Swing Presentation Layer!) which made the project take up to 4 years (instead of a lot less if they listened and understood) and I personally whitnessed another major player in that industry (Insurance) turn down their "reusable" framework and solution for lack of both flexibility and performance...
13 . At 8:36 PM on Mar 30, 2006, Tom Pridham wrote:
  Click to reply to this thread Reply

Re: The State of "The Design"

Great article but I completely disagree with the whole DTO discussion. I will buy the book though, because I am a curious individual :-)

Regards,
Tom
Regards,
Tom Pridham
Technologist & Founder
Coastal Software Solutions Inc.
office: 813.600.5053
Pridham@Mindspring.com
14 . At 1:30 PM on Apr 1, 2006, Jojo Paderes wrote:
  Click to reply to this thread Reply

Re: The State of "The Design"

Erwin points out exactly what most developers struggle when deciding if a DTO will simplify the design for the ui data binding. One good example is displaying data that will come from multiple domain models (i.e. Hibernate-based domain models) in the web screen. There are cases (and there are lots of them) where it's more convenient to consolidate the data from these domain models into one DTO or Value Object (and use JSTL to display them in JSPs). And it makes the design by contract approach simpler between the Java UI layer and the domain layer (though the mapping of DTO with the domain model can be a pain).

And as what Erwin pointed out in one of his other posts, using string literals to invoke methods reflectively as shown in Steven's Dozer class is not a good idea in my opinion. What would happen if I refactor (rename) that method? Do I have to search for those string literals using that method name? That's complicating things for dear developer. It's like using WS SOAP internally in the application?!

I noticed that most of the Spring code examples uses the domain model directly in the ui layer (which in some cases there's a good reason for doing it). And if we are going to label JavaBean conventions as "anti-encapsulation", would that mean the Spring code examples are using a bad design approach since using Hibernate domain models (or just domain model for some samples that doesn't use Hibernate) are not true objects or somewhat a close relative of a DTO?

Sometimes a DTO can make things simple (especially for the UI layer) than trying to over engineer the design and implementation just because we want too much encapsulation.

Btw, we're using Spring and Hibernate for our projects and I would say it's a lot better than your old school EJB infrastructure. We just do the simplest thing that could possibly work. :-)

thread.rss_message