The Artima Developer Community
Sponsored Link

Weblogs Forum
Oh No! DTO!

31 replies on 3 pages. Most recent reply: Apr 26, 2007 2:45 AM by Risto Peränen

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 31 replies on 3 pages [ « | 1 2 3 | » ]
Robert C. Martin

Posts: 111
Nickname: unclebob
Registered: Apr, 2003

Re: Oh No! DTO! Posted: Feb 27, 2004 10:23 PM
Reply to this message Reply
Advertisement
> While I agree with him about Objects and Data Structures,
> the point that Rob is missing is that it is quite common
> to start with a Data Structure and have it evolve toward
> an Object as your code changes over time.

I view this as a design flaw. Indeed, I think data structures and objects should evolve apart. Often I'll start with what I think is an object only to find that it is really a hybrid of an object with behavior and a data structure with none. In such cases I split them apart.

For example, I might have an Employee record with a calculatePay method. It might also have a getName and setName method. The name has nothing to do with calculating pay, and so should not be part of the object. The name, and other data irrelevant to calculating pay, should be moved into a data structure separate from the object. IMHO.

Rick Kitts

Posts: 48
Nickname: rkitts
Registered: Jan, 2003

Re: Oh No! DTO! Posted: Feb 28, 2004 1:18 PM
Reply to this message Reply
> I reject this argument rather vehemently. We do no
> service to our profession by dumbing it down. It is
> better to educate than legislate.

I understand this position, though it's not what I was suggesting. Don't think of it as dumbing down. Think of it as raising the level of abstraction. I see no diservice in the crafting a set of guidelines which allow an average developer to construct a robust and reliable system without having to wander far from the problem domain. We'll not realize this goal until our best practices are rooted in safe, not elegant.

>
> Rather than teach practices that are "safe" for the
> mediocre developer; we need to teach the mediocre
> developer how to be better. We don't do that by
> recommending practices that we justify only with: "We want
> you to do this because we're afraid you're a slug."

This last is, I think, well overstated. Nothing in the argument suggests this derision. There is, and will continue to be, an average developer. This is not bad. It does not suggest they suck, or are incompetent. Indeed, by definition, most developers are average. My experience is that average, at the moment has the profile I outlined. Come to work, do a good job, go home and live life. Life is not development. I'm willing to admit that I find it difficult to comprehend why anyone would not wish to deeply consider the implications of the lines of code they write. Why they would not recognize that they've suddenly created differing semantics for setting a DTO member, and seek to fix it. But it remains the case, despite my bewilderment and hope otherwise, that most do not. Coherence as a goal falls quickly to the wayside when in contention with meeting a schedule. I suspect most developers would work extra hours to fix this sort of problem. Once or twice. But it's not once or twice it's forever. People get tired and keeping up with this sort of kruft accretion requires a commitment that most people aren't interested in maintaining.

So why suggest something that *can* become unsafe. Saving typing is a poor excuse I think.

Cedric Beust

Posts: 140
Nickname: cbeust
Registered: Feb, 2004

Re: Oh No! DTO! Posted: Feb 28, 2004 7:19 PM
Reply to this message Reply
> I view this as a design flaw. Indeed, I think data
> structures and objects should evolve apart. Often
> I'll start with what I think is an object only to find
> that it is really a hybrid of an object with behavior and
> a data structure with none. In such cases I split them
> apart.
>
> For example, I might have an Employee record with a
> calculatePay method. It might also have a getName and
> setName method. The name has nothing to do with
> calculating pay, and so should not be part of the object.
> The name, and other data irrelevant to calculating pay,
> , should be moved into a data structure separate from the
> object. IMHO.

Agree with this example, but it's a rigged one :-)

How about: hourlyRate and calculatePay() ?

These two things belong in the same class, in my opinion, an d you should therefore provide a getHourlyRate().

Where you say "it's a design flaw", I tend to say "nobody can predict how your object will evolve", so I recommend to use getters and setters everywhere for uniformity and leave the room open for future evolutions.

Using direct access to fields can make your code impossible to evolve.

--
Cedric
http://beust.com/weblog

Gregg Wonderly

Posts: 317
Nickname: greggwon
Registered: Apr, 2003

Re: Oh No! DTO! Posted: Feb 28, 2004 11:33 PM
Reply to this message Reply
> To give a contrarian example, though, the Jini designers
> tended to do just what you suggest. The Jini service item,
> for example, which returns three pieces of information
> from a Jini lookup service across the network to the
> client, is a "data transfer object" in J2EE parlance. And
> the service item uses public fields to hold those three
> pieces of data. That works fine when used as the designers
> intended.

This was the same exact example I wanted to use Bill! But my issue with this particular DTO is the fact that it is handed back from another object that has no way to iterate. You have to get all ServiceItem objects at the same time.

In this particular case, ServiceItem.service (as you know Bill) is assigned the value of the unmarshalled object that is the services 'code'. There are also Entry objects in an array, in the ServiceItem.attributeList field. These are also deserialized by the Object that ServiceItem comes from.

In my case, I really want to be able to look through the Entry[] before causing the download of the service object and deserialization. In the case of dialup networking and a large number of large services, we can't search the services' Entry values without first downloading all of them!

In this case, there should be a getter for all of the fields that cause deserialization to occur. It should be possible to manage the impact of such objects on the users abilities to manage their session.

As more people become fluent in network centric computing and start to understand the whole scale issue, it will become more apparent that getters are an important part of making it possible to extend the functionality of an object with opaqueness to the users of the object.

I, really avoid public fields that are not declared final...

Bill Venners

Posts: 2249
Nickname: bv
Registered: Jan, 2002

Re: Oh No! DTO! Posted: Feb 29, 2004 2:48 PM
Reply to this message Reply
> > Immutable objects have several advantages. You can
> cache
> > them. You can pass them to methods without making a
> copy.
> > You can return them to methods without making a copy.
> > That's the value (value, get it?) of data-oriented
> objects
> > that have private methods with getters and setters.
>
> Do you think you could achieve the same ends with public
> final variables that are set in a constructor?

Such a class is also immutable. I don't usually do immutables that way in Java because it's idiomatic to do immutables with private variables and get methods. That's how JavaBeans do it, how exceptions do it, how events do it. That idiom is all over the Java APIs. I tend to use the idioms in a language because I think it helps people read the code. I wouldn't use get methods in C#, for example, I'd use properties. I happen to personally prefer that approach. I like C#'s properties approach better than Java's get methods approach, but I'm somehow not so offended by get methods that I feel the need to avoid them in Java.

On the other hand, if I come into a team as a consultant and they have decided to do immutables with public final variables, then I would do it that way on their project if that's what they wanted. On that project, that's what those people would be used to seeing.

I can't find it now, so I think maybe I never published it. But in one of my interviews with Gosling, he said that for a while in one of the early iterations of Oak (which became Java), he had some kind of properties feature in there. He said everyone he showed it to went, "bleh," so he lost his confidence in it and took it out. He seemed to regret having taken it out at the time I was interviewing him, though, and seemed dissappointed with the JavaBeans get/set method approach that was kind of tacked on later. The get/set approach isn't the best design, perhaps, but it works and is idiomatic and not so much of a burden, so in Java I just use it.

Mike Williams

Posts: 1
Nickname: mdub
Registered: Feb, 2004

Re: Oh No! DTO! Posted: Feb 29, 2004 11:39 PM
Reply to this message Reply
> Uniformity is crucial.

I also prefer to stick to a uniform data-access pattern, rather than have to make the distinction between "object" and "data-structure".

Though I can see where UncleBob is coming from: all that extra getX/setX code is painful to write, and "foo.x" is more readable than "foo.getX()".

But this as a idiosyncrasy of Java/C++. I love that the whole issue goes away in Ruby, where (1) you have to provide accessor-methods, as direct member-variable access is impossible, and (2) accessor-methods are invoked with a simpler, more meaningful syntax (e.g. "foo.x"). The best of both worlds!

Cedric Beust

Posts: 140
Nickname: cbeust
Registered: Feb, 2004

Re: Oh No! DTO! Posted: Mar 2, 2004 1:01 PM
Reply to this message Reply
> But this as a idiosyncrasy of Java/C++.

Not only that, it's an idiosyncrasy of using bad tools. Typing laziness is not an excuse to explain poor readability of your code. Use an IDE and it will assist you in typing these long names.

Remember that code is much more often read than it is written, so it pays off to spend a few extra minutes writing it correctly.

> I love that the
> whole issue goes away in Ruby, where (1) you have
> to provide accessor-methods, as direct member-variable
> access is impossible, and (2) accessor-methods are invoked
> with a simpler, more meaningful syntax (e.g. "foo.x").
> The best of both worlds!

Absolutely. I just blogged about exactly this, but on Groovy...

http://beust.com/weblog

--
Cedric

Peter Breton

Posts: 1
Nickname: portabella
Registered: Mar, 2004

Re: Oh No! DTO! Posted: Mar 15, 2004 3:16 PM
Reply to this message Reply
I think Bob's whole post turns on the word <i>aghast</i>.

I tend to write DTOs with getters and setters, because of the convenience which comes with using Java Beans. I have a little code generator that cranks them out, so it's truly the work of a minute or two to generate a new one.

But I have no problem with using public variables when appropriate, especially when they can be changed later if/when necessary.

The real problem isn't the student objecting, or suggesting a different route; it's his *aghastness* at something that Just Doesn't Matter That Much.

J. B. Rainsberger

Posts: 12
Nickname: jbrains
Registered: Jan, 2004

Re: Oh No! DTO! Posted: Apr 24, 2004 12:18 PM
Reply to this message Reply
I think everyone's missing the point, so either that's true or what I'm about to say is incredibly stupid.

DTO stands for "data transfer object". Why is this an object at all? The data being transferred is nothing more than a typed message sent from one package (tier, layer, whatever) to another. Look again: /it's a message/! The fact that we implement it as an object is nothing more than an accident of the programming language we work with (Java or C#) and our conditioning. If Java/C# had direct support for the concept of a "message" (in the Messaging sense; not in the OO/method sense), then we would surely use /that/ rather than an object.

But wait! There's this neat thing called a Map (in Java; I don't know the C# equivalent) that stores typed name/value pairs... much like a so-called data transfer object. Why not use that?

Indeed, why not? My data transfer messages are Map messages, and it works just beautifully, thank you. I don't need the compiler to stop me from making mistakes I don't make -- that's why I have tests.

Generic data transfer... simple, direct, and it works. It also completely obviates the need for this discussion. What could be better?

Matt Gerrans

Posts: 1153
Nickname: matt
Registered: Feb, 2002

Re: Oh No! DTO! Posted: Apr 27, 2004 2:00 PM
Reply to this message Reply
> ...thing called a Map (in Java; I don't know the C# equivalent) that stores typed name/value pairs...

It's IDictionary. Interestingly, they chose to come up with a new word there, but with its most prominent implementation Hashtable, they chose to shamelessly copy Java, complete with the uncapitalized 't'. (I prefer Map -- who needs all these annoying and pedantic "I" prefixes in front of interfaces and why choose a ten letter synonym over a three letter word? (it's like people who say "utilize" instead of "use" -- ooh, how erudite!))

> ...much like a so-called data transfer object. Why not use that?

This also comes quite naturally in Python and Ruby and the like where creating maps is a very lightweight task (coding-wise).

> Generic data transfer... simple, direct, and it works. It also completely obviates the need for this discussion.
> What could be better?


It seems you've moot-ilated the question.

Dave Benjamin

Posts: 10
Nickname: ramenboy
Registered: Nov, 2003

Re: Oh No! DTO! Posted: Apr 28, 2004 12:30 PM
Reply to this message Reply
> > Generic data transfer... simple, direct, and it
> works. It also completely obviates the need for this
> discussion.
> > What could be better?

>
> It seems you've moot-ilated the question.

Not so fast! I have tried this approach in Java and it was more trouble than it was worth. Heterogeneously-typed maps in statically-typed languages are a recipe for ClassCastExceptions, and they won't play well with Java Generics. As someone looking forward to writing cast-free code soon, I simply can't put my money on this approach, as much as I'd like to.

I agree with Bob. Data structures and objects are different creatures. The paranoia about not being able to convert a data structure to an object is unnecessary because a) refactoring tools can ease the transition from data structure to object, and b) making such a transition should be infrequent.

The whole point of a DTO, in my opinion, is to get data *into* the object, not to *be* the object. It provides a practical answer to the question, "How do I build a layered system but still preserve encapsulation?" In other words, DTOs help us avoid writing getters and setters for every attribute when we need to share data among different layers or subsystems. DTOs don't need to be objects any more than argument lists do; in fact, I see them as a sort of hack around Java's (and other languages') lack of support for named parameters.

Dave

Radu Muresan

Posts: 1
Nickname: cavey
Registered: May, 2004

Re: Oh No! DTO! Posted: May 4, 2004 8:34 AM
Reply to this message Reply
I definitely go for the getters/setters approach. Just consider this very simple example: I have a system based on some invasive technology (say EJBs) and I'm using DTO. I migrate it to something less invasive (say JDO/Hibernate) and hopefully I will have the chance to use my domain objects as dto's. That would be very nice indeed.
Now, if I would have gone with the direct access approach - I would have to modify my domain objects (but I guess having public fields there is out of the question) or modify the entire referring code.

And you'll never know when a DTO might perish (or appear out of the blue).

The getter/setter approach also works better for the reverse of the scenario I presented above.

Consistency is also good...

Leendert Brouwer

Posts: 2
Nickname: daholygoat
Registered: Jul, 2004

Re: Oh No! DTO! Posted: Jul 1, 2004 10:07 AM
Reply to this message Reply
First off, I agree with Cedric Beust who said that it is common to refactor data structures into objects occasionally. At the other hand I agree with the original statement by the author. There's a middle way I tend to choose with DTO's. I create one method getAttribute(String name) and a setAttribute(String attrib, String value) through which I access all DTO members in its clients' code. So if a getter/setter needs an exceptional approach later, I can take care of that particular member in the generic access method instead of changing the code for every client of the DTO.

Jim Cakalic

Posts: 2
Nickname: jimc
Registered: Aug, 2005

Re: Oh No! DTO! Posted: Aug 1, 2005 3:15 PM
Reply to this message Reply
> I think everyone's missing the point, so either that's
> true or what I'm about to say is incredibly stupid.
>
> DTO stands for "data transfer object". Why is this an
> object at all?

THANK YOU! I completely agree that a DTO can easily be considered just a message that has been raised to status of an object. While there is a place for such an object (aka Command Pattern), many developers use it as a crutch. They have not yet IMO made the paradigm shift to object-oriented thinking. They apply various patterns documented in tomes such as <i>Core J2EE Patterns</i> and <i>Patterns of Enterprise Application Architecture</i> without really considering the context or consequences of the pattern. (Is there a name for this anti-pattern? Maybe Pattern Promiscuity or Pattern Puerility?)

In <i>Patterns of Enterprise Application Architecture</i>, Mr. Fowler alludes to this failure to make the "paradigm shift" when discussing the Domain Model pattern. He cites the comfort level of the development team with domain objects to be a key factor in determining when to use the pattern because "learning how to design and use a Domain Model is a significant exercise." The opposite of Domain Model is Transaction Script which "Organizes business logic by procedures." He says that object bigots prefer domain models to transaction scripts. If someone ever calls me an object bigot I'll wear it as a badge of honor.

When speaking specifically about the Data Transfer Object pattern, he states the intent as "An object that carries data between processes." Note that it is between <b>processes</b> and not between <b>layers</b> within a process. If you are using DTO between layers within a process then you are applying the pattern outside of the context it is meant to address. (Remember a pattern being "a solution to a recurring problem in a context?" Wrong context, wrong solution!) Even when used correctly, he describes it as "one of those objects our mothers told us never to write" and a "usually hateful beast."

<i>Refactoring</i> documents at least two refactorings that speak to this subject. In the conclusion of <b>Replace Record with Data Class</b> Mr. Fowler states: "You now have a dumb data object. I has no behavior yet but further refactoring will explore that issue." The point is that you have found a clumping of data that appears to be cohesive and are optimistic that behavior will eventually reveal itself. Similarly, in <b>Introduce Parameter Object</b> he states: "once you have clumped together parameters, you soon see behavior that you can also move into the new class."

A previous poster referred to Arthur Riel and cited heuristic 3.3 from his (highly recommended) book <i>Object-Oriented Design Heuristics</i>. That poster didn't mention these other related heuristics captured there: 2.1 All data should be hidden within its class and 2.9 Keep related data and behavior in one place. Mr. Martin's argument is that I haven't proven this "data clump" to be an object and should treat it as merely a "data clump" until I do. My hard-fought-for sensibilities (still evolving) tell me that I should assume that it <i>is</i> an object until you prove me wrong.

It has become my sincere opinion that DTO is one of the most pervasive and hideous antipatterns at work in the practicing Java development community. Not because I "religously" follow the heuristics and refactorings cited above. But because the application of this pattern outside its context gives implicit approval for thinking in terms of a separation of data and behavior. Its promiscuous use results in construction of systems that are action-oriented, not object-oriented. (Another nod to Mr. Riel -- chapter 3.) It encourages developers to solve problems primarily in terms of services that operate on data. Service-oriented, when used in the context of the internal design of a single application, is a euphemism for procedural. At least for me, applying principles similar to those cited above are a continuous sanity check for maintaining object-oriented thinking.

Mr. Martin teaches the course "Object-Oriented Overview for Managers" for ObjectMentor. One of the sections is entitled "OO is hard." I'd be curious what he has to say to the manager who asks, "Why shouldn't I just decompose my system as Java data structures with service classes that operate on them? Wouldn't that work?" But that wouldn't really be taking the "OO is hard" high road would it? To quote Tom Hanks' character in <i>A League of Their Own</i>: "If it wasn't hard everybody would do it. It's the <b>hard</b> that makes it <b>great</b>."

As for me, I will not go gently into that good night!

Regards,
Jim Cakalic

M. Eric DeFazio

Posts: 10
Nickname: defazio
Registered: May, 2005

DTO=Mana From Heaven Posted: May 14, 2006 10:04 PM
Reply to this message Reply
DTOs are a godsend, mana from heaven, the best thing EVER. I'm currently working with a few "Fowler Followers"/Smalltalkers who are starting to see the light in my arguments about why DTOs/the Anemic Domain model is GREAT. But First things last...I'd like to chime in on a few reasons why I think it's good practice to use getters and setters on DTOs.

Firstly the JavaBeans Api, (as mentioned eariler)

Or if you ever get in a situation where you are shipping a good deal of data (a complex data structure) you may not want to expose the low-level internals of how the data is stored (here I'm thinking of an Array of things) it's better that you don't have direct access to the thing (Here I want a addThingy() method without doing an arraycopy to a newly sized array each time)

public MyDto {
private List thingys = new ArrayList();

public void addThingy(Thingy t) {
thingys.add(t);
}


public Thingy[] getThingys() {
return (Thingy[])thingys.toArray(new Thingy[0]);
}
}
(The above code will allow you to serialize the DTO through JAXRPC since it's a well defined type)

Additionally, what happens if "null" means something, so you want to use the Java Wrapper types. For instance if you want to have a variable "cost" where it could be null (not set) as apposed to 0 (the default integer value)... from an outsiders persepctive, I just want to set it with an int as apposed to doing cost = new Integer(3);

Integer cost;
public void setCost (int cost){
this.cost(new Integer(cost));
}
Also, if you wanted to do integrate a Proxy or AOP on a DTO object (for Locking and Versioning) you can do this by using an introduction or method injection... I dont think you'll be able to do that when you are directly modifying a field on the DTO.

I've found that in Java using getters/setters gives you more options and flexibility to integrate with existing APIs (JavaBeans/JAXB/JAXRPC to Expose as web services/etc)

Finally, I think it's good to be consistent, there is a reason that PMD/Checkstyle/etc. is barking when you are doing field level access, because it's nice when everyone is consistent... is it really worth not typing in the 7 extra characters to be a non-conformist?...

thing.name
thing.getName()


...is it that difficult to create private variables in a DTO and then "generate getters and setters" in your IDE?

Cheers,
E.

Flat View: This topic has 31 replies on 3 pages [ « | 1  2  3 | » ]
Topic: Oh No!  DTO! Previous Topic   Next Topic Topic: Comparing Inner Class/Closure Proposals


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us