Hi David L,

I imagine the “extra step” and “redirection” are the need to create both  the 
SomeDTO and the SomeImpl?

Thinking about this a bit more I’m reminded that sometimes I end up thinking 
that putting that first “this” parameter back into every method that C++ took 
out might be a good idea :-)

I started down this rabbit hole by thinking, what if we think of DTOs as 
primitive data types, like int or long, as much as possible.

For your “business method” example, a static method 

class SomeHelper {
  public static String calculateFooBar(SomeDTO data) {return data.foo + “:” + 
data.bar;}
}

makes perhaps more sense than the SomeImpl I proposed before.  But if you want 
to do something more complicated, a builder to hold state (outside the DTO, 
presumably) can make sense:

class SomeBuilder {
  String foo;
  String bar;
  SomeBuilder(SomeDTO data) {foo = data.foo;bar = data.bar;}
  public void append(SomeDTO moreData) {
    data.foo = data.foo + ”,” + moreData.foo;
    data.bar = data.bar + “,” + moreData.bar;
  }

  public String calculateFooBar() {return foo + “:” + bar;}
}

So I wonder what you end up with if you have
-DTOs
-a “Helper” class with only static methods taking one or more DTOs
-a bunch of “builders” that hold state from one or more DTOs during multi-step 
calculations.

I suppose there also needs to be some code to call some of these 
methods/builders, but I think you need that anyway.

thanks
david jencks




> On Oct 15, 2016, at 5:28 PM, David Leangen <o...@leangen.net> wrote:
> 
> 
> Hi David J.,
> 
> That is an interesting perspective.
> 
> Also based on the ideas proposed by Peter, and after a bit of 
> experimentation, these are my thoughts:
> 
> * Java object encapsulation “works", but only if we assume that there is
>     no such thing as reflection. Since an object can be introspected, it means
>     that there is no “complete” encapsulation, only “weak” encapsulation.
> 
>      —> True. Important if thinking about security, maybe, but perhaps not
>             very convincing to me to change my thinking.
> 
> * DTOs are not real “Value Objects” because normally a VO should be immutable.
>     However, if all we make are copies, and both the producer and consumer 
> understand
>     that it is a copy being shipped, then in the end, I cannot see a problem. 
> It will cause me
>     to change some habits, but I don’t see a problem.
> 
> * Java8 and its “functional” flavour have really started to interest me.
> 
> 
> Based mostly on the last two thoughts, I have tried using the pattern I wrote 
> in my earlier post. In essence:
> 
> * API interface - determines the contract with the rest of the world
> * DTO - for transmitting and serializing (essential for a working system)
> * Implementation object - usually Value Objects, but sometimes Entities
> 
> By following most of the DTO rules, which generally means (1) make 
> serialisable data public, (2) provide a no-arg public constructor, and (3) 
> have a tree-like structure that only contains other “DTO-type” objects, the 
> DTO can be combined with the implementation.
> 
> This completely eliminates an extra step.
> 
> No longer required:  serialized data —> DTO —> domain object
> 
> New method: serialized data —> DTO (==domain object)
> 
> I have even started to make my “simple” DTOs (i.e. pure VOs with little or no 
> behaviour) part of the API instead of the impl.
> 
> I have been very pleased with the results so far. However, if we don’t 
> provide the possibility to relax the rules on the DTOs a bit, this will no 
> longer be possible. I would be really sad to not be able to use this pattern, 
> unless of course somebody has come up with a better / alternate solution.
> 
> 
> What you propose below seems like it would encapsulate well, but it seems to 
> me that the extra step of redirection would cause duplicate work. No?
> 
> 
> Cheers,
> =David
> 
> 
>> On Oct 16, 2016, at 1:10 AM, David Jencks <david_jen...@yahoo.com.INVALID> 
>> wrote:
>> 
>> A while ago Peter said something about DTOs violating data hiding or 
>> encapsulation and I decided that if you think of the DTO as a primitive data 
>> type they don’t.   Following this line of thinking (which I have not been 
>> able to try out in practice, just as thought experiments) you’d have
>> 
>> public class SomeDTO extends DTO {
>> public String foo;
>> public String bar;
>> }
>> 
>> public interface SomeInterface {
>> SomeDTO data(); //I’m not sure this is needed
>> String calculateFooBar();
>> }
>> 
>> public class SomeImpl {
>> final SomeDTO data;
>> public SomeImpl(SomeDTO data) {this.data = data;}
>> public SomeDTO data() {return data;}
>> public String calculateFooBar() {return data.foo + “:” + data.bar;}
>> }
>> 
>> I’m curious how this would work out in an actual situation, especially in 
>> knowing fi the “data()” accessor is needed.  I’d hope it would only be 
>> needed for serialization purposes.
>> 
>> thanks
>> david jencks
>> 
>>> On Oct 14, 2016, at 9:52 PM, David Leangen <apa...@leangen.net> wrote:
>>> 
>>> 
>>> Hi!
>>> 
>>> I only noticed now that according to the RFC, DTOs cannot contain methods. 
>>> I can understand why this is so, and I do not object.
>>> 
>>> However, I have found a very practical design pattern whereby I use classes 
>>> that act both as DTOs and domain value objects. In effect, this means that 
>>> they are DTOs with methods. I am willing to pay the price of having 
>>> “bloated” DTOs for this convenience.
>>> 
>>> 
>>> Would there be any way to allow configuration to permit this?
>>> 
>>> If that is out of the question then any suggestions as to what I could do 
>>> so as to not have to have “duplicate” classes (DTOs and domain VOs)?
>>> 
>>> 
>>> Example:
>>> 
>>> Domain object API
>>> 
>>> public interface SomeObject {
>>> String foo();
>>> String bar();
>>> String calculateFoobar();
>>> }
>>> 
>>> Implementation
>>> 
>>> public class SomeObjectDTO extends DTO implements SomeObject {
>>>  public String foo;
>>>  public String bar;
>>> 
>>>  public SomeObjectDTO() {}
>>> 
>>>  public SomeObjectDTO( String aFoo, String aBar ) {
>>>      foo = aFoo; bar = aBar;
>>>  }
>>> 
>>>  @Override public String foo() { return foo; }
>>>  @Override public String bar() { return bar; }
>>>  @Override public String calculateFoobar() { return foo + “:” + bar; }
>>> }
>>> 
>>> 
>>> I like the above because:
>>> * No duplication
>>> * As a DTO, can be sent over the wire and serialised
>>> * Implements the domain API
>>> 
>>> 
>>> Cheers,
>>> =David
>>> 
>>> 
>> 
> 

Reply via email to