You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by David Leangen <ap...@leangen.net> on 2016/10/15 04:52:30 UTC

[Converter] DTOs with methods?

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



Re: [Converter] DTOs with methods?

Posted by David Bosschaert <da...@gmail.com>.
Hi David L,

I've implemented an initial version here:
https://svn.apache.org/viewvc?view=revision&revision=1765430

I had to rename the methods a little bit. The to() has the actual
implementation type, just as before. The new method added is target() which
is where you can specify how to view the target implementation method. I
added a unit test at [1] which does:

MyDTOWithMethods dto =
converter.convert(src).target(MyDTO.class).to(MyDTOWithMethods.class);

Hope this works for you...

Cheers,

David

[1]
https://svn.apache.org/viewvc/felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java?r1=1765430&r2=1765429&pathrev=1765430

On 18 October 2016 at 11:49, David Leangen <os...@leangen.net> wrote:

>
> HI David B.,
>
> Yup, something like that would do just fine!!
>
> Thanks a lot.
>
>
> Cheers,
> =David
>
>
> > On Oct 18, 2016, at 7:43 PM, David Bosschaert <
> david.bosschaert@gmail.com> wrote:
> >
> > Hi David L,
> >
> > The as() method (at least in its current incantation) say something about
> > how to treat the source object - the thing you are converting from. So in
> > your example
> >  myDtoWithMethods =
> > converter.convert(map).as(PlainDTO.class).to(DtoWithMethods.class)
> >
> > it would try to treat the source map as a PlainDTO - which obviously will
> > fail.
> >
> > I guess what you're looking for is a way to say: 'create a target object
> > from this class, but treat it as if it was that class', so maybe
> something
> > like this?:
> >  myDtoWithMethods =
> > converter.convert(map).to(PlainDTO.class).in(DtoWithMethods.class)
> >
> > This is not yet implemented, it's just a suggestion. WDYT?
> >
> > Cheers,
> >
> > David
> >
> > On 18 October 2016 at 11:27, David Leangen <os...@leangen.net> wrote:
> >
> >>
> >> Hi David B.,
> >>
> >> Thanks for this suggestion. That would indeed work nicely. As you say,
> it
> >> requires an extra class, but at least there is very little duplication,
> at
> >> least converting TO something.
> >>
> >> Converting TO:
> >>
> >>> Map m = converter.convert(myDtoWithMethods).as(PlainDTO.
> >> class).to(Map.class)
> >>
> >> When converting FROM something, would this work?
> >>
> >> myDtoWithMethods = converter.convert(map).as(PlainDTO.class).to(
> >> DtoWithMethods.class)
> >>
> >> If so, then I think this would work just fine!
> >>
> >>
> >> Cheers,
> >> =David
> >>
> >>
> >>> On Oct 18, 2016, at 6:13 PM, David Bosschaert <
> >> david.bosschaert@gmail.com> wrote:
> >>>
> >>> Hi David L,
> >>>
> >>> Recently I added the 'as()' method to the converter, which is really
> >> meant
> >>> to disambiguate source objects. Let's say you have an object that is
> >> both a
> >>> JavaBean as well as implementing an interface. The Converter spec will
> >>> specify some 'priority' rules for this, but they may not always be what
> >> you
> >>> want. The as() method can be used to treat the source object in a
> >>> particular way.
> >>>
> >>> For example, let's say your MyClass extends MyBean implements Intf1
> >>> Let's say you want to force the converter to look at an instance of
> >> MyClass
> >>> as Intf1.
> >>>
> >>> You could then do
> >>> converter.convert(myobj).as(Intf1.class).to(Map.class)
> >>>
> >>> Would it help to use this for the DTO+methods as well?
> >>> You might have:
> >>>
> >>> Class PlainDto {
> >>> public String foo;
> >>> }
> >>>
> >>> Class DtoWithMethods extends PlainDto {
> >>> public int someMethod() {}
> >>> }
> >>>
> >>> And then maybe use these via:
> >>> converter.convert(myDtoWithMethods).as(PlainDTO.class).to(Map.class)
> >>> ?
> >>>
> >>> It would require a separate class that follows the pure DTO rules...
> >>>
> >>> Cheers,
> >>>
> >>> David
> >>>
> >>>
> >>> On 18 October 2016 at 09:49, David Leangen <os...@leangen.net> wrote:
> >>>
> >>>>
> >>>> Hi David B.,
> >>>>
> >>>> Thanks. I think you’re right, the spec is quite clear.
> >>>>
> >>>> If I wanted to treat any class like a DTO (ignore the methods and use
> >> only
> >>>> the public fields — just like before the recent changes made to the
> code
> >>>> base), can you think of any way?
> >>>>
> >>>> Perhaps having “strict” mode to follow the spec to the letter, and a
> >> less
> >>>> strict mode for people like me?
> >>>>
> >>>>
> >>>> wdyt?
> >>>>
> >>>> Cheers,
> >>>> =David
> >>>>
> >>>>
> >>>>> On Oct 18, 2016, at 5:45 PM, David Bosschaert <
> >>>> david.bosschaert@gmail.com> wrote:
> >>>>>
> >>>>> Hi all,
> >>>>>
> >>>>> The OSGi spec for DTOs is pretty clear. Section 57.2 of the R6 Core
> >> spec
> >>>>> states:
> >>>>>
> >>>>> "Data Transfer Objects are public classes with no methods, other than
> >> the
> >>>>> compiler supplied default
> >>>>> constructor"
> >>>>>
> >>>>> Therefore I would be reluctant to use a different definition for the
> >>>>> Converter.
> >>>>>
> >>>>> OTOH I think that there are a couple of options if you like to have
> >> 'DTOs
> >>>>> with behaviour':
> >>>>> * you could use JavaBeans. The getters/setters are understood by the
> >> the
> >>>>> converter and will result in similar behaviour, but the beans can
> have
> >>>>> other methods too.
> >>>>> * registry your own converter rules for these classes.
> >>>>>
> >>>>> Cheers,
> >>>>>
> >>>>> David
> >>>>>
> >>>>> On 16 October 2016 at 04:18, David Jencks <david_jencks@yahoo.com.
> >>>> invalid>
> >>>>> wrote:
> >>>>>
> >>>>>> 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 <os...@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_jencks@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 <ap...@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
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>
> >>>>>>
> >>>>>>
> >>>>
> >>>>
> >>
> >>
>
>

Re: [Converter] DTOs with methods?

Posted by David Leangen <os...@leangen.net>.
HI David B.,

Yup, something like that would do just fine!!

Thanks a lot.


Cheers,
=David


> On Oct 18, 2016, at 7:43 PM, David Bosschaert <da...@gmail.com> wrote:
> 
> Hi David L,
> 
> The as() method (at least in its current incantation) say something about
> how to treat the source object - the thing you are converting from. So in
> your example
>  myDtoWithMethods =
> converter.convert(map).as(PlainDTO.class).to(DtoWithMethods.class)
> 
> it would try to treat the source map as a PlainDTO - which obviously will
> fail.
> 
> I guess what you're looking for is a way to say: 'create a target object
> from this class, but treat it as if it was that class', so maybe something
> like this?:
>  myDtoWithMethods =
> converter.convert(map).to(PlainDTO.class).in(DtoWithMethods.class)
> 
> This is not yet implemented, it's just a suggestion. WDYT?
> 
> Cheers,
> 
> David
> 
> On 18 October 2016 at 11:27, David Leangen <os...@leangen.net> wrote:
> 
>> 
>> Hi David B.,
>> 
>> Thanks for this suggestion. That would indeed work nicely. As you say, it
>> requires an extra class, but at least there is very little duplication, at
>> least converting TO something.
>> 
>> Converting TO:
>> 
>>> Map m = converter.convert(myDtoWithMethods).as(PlainDTO.
>> class).to(Map.class)
>> 
>> When converting FROM something, would this work?
>> 
>> myDtoWithMethods = converter.convert(map).as(PlainDTO.class).to(
>> DtoWithMethods.class)
>> 
>> If so, then I think this would work just fine!
>> 
>> 
>> Cheers,
>> =David
>> 
>> 
>>> On Oct 18, 2016, at 6:13 PM, David Bosschaert <
>> david.bosschaert@gmail.com> wrote:
>>> 
>>> Hi David L,
>>> 
>>> Recently I added the 'as()' method to the converter, which is really
>> meant
>>> to disambiguate source objects. Let's say you have an object that is
>> both a
>>> JavaBean as well as implementing an interface. The Converter spec will
>>> specify some 'priority' rules for this, but they may not always be what
>> you
>>> want. The as() method can be used to treat the source object in a
>>> particular way.
>>> 
>>> For example, let's say your MyClass extends MyBean implements Intf1
>>> Let's say you want to force the converter to look at an instance of
>> MyClass
>>> as Intf1.
>>> 
>>> You could then do
>>> converter.convert(myobj).as(Intf1.class).to(Map.class)
>>> 
>>> Would it help to use this for the DTO+methods as well?
>>> You might have:
>>> 
>>> Class PlainDto {
>>> public String foo;
>>> }
>>> 
>>> Class DtoWithMethods extends PlainDto {
>>> public int someMethod() {}
>>> }
>>> 
>>> And then maybe use these via:
>>> converter.convert(myDtoWithMethods).as(PlainDTO.class).to(Map.class)
>>> ?
>>> 
>>> It would require a separate class that follows the pure DTO rules...
>>> 
>>> Cheers,
>>> 
>>> David
>>> 
>>> 
>>> On 18 October 2016 at 09:49, David Leangen <os...@leangen.net> wrote:
>>> 
>>>> 
>>>> Hi David B.,
>>>> 
>>>> Thanks. I think you’re right, the spec is quite clear.
>>>> 
>>>> If I wanted to treat any class like a DTO (ignore the methods and use
>> only
>>>> the public fields — just like before the recent changes made to the code
>>>> base), can you think of any way?
>>>> 
>>>> Perhaps having “strict” mode to follow the spec to the letter, and a
>> less
>>>> strict mode for people like me?
>>>> 
>>>> 
>>>> wdyt?
>>>> 
>>>> Cheers,
>>>> =David
>>>> 
>>>> 
>>>>> On Oct 18, 2016, at 5:45 PM, David Bosschaert <
>>>> david.bosschaert@gmail.com> wrote:
>>>>> 
>>>>> Hi all,
>>>>> 
>>>>> The OSGi spec for DTOs is pretty clear. Section 57.2 of the R6 Core
>> spec
>>>>> states:
>>>>> 
>>>>> "Data Transfer Objects are public classes with no methods, other than
>> the
>>>>> compiler supplied default
>>>>> constructor"
>>>>> 
>>>>> Therefore I would be reluctant to use a different definition for the
>>>>> Converter.
>>>>> 
>>>>> OTOH I think that there are a couple of options if you like to have
>> 'DTOs
>>>>> with behaviour':
>>>>> * you could use JavaBeans. The getters/setters are understood by the
>> the
>>>>> converter and will result in similar behaviour, but the beans can have
>>>>> other methods too.
>>>>> * registry your own converter rules for these classes.
>>>>> 
>>>>> Cheers,
>>>>> 
>>>>> David
>>>>> 
>>>>> On 16 October 2016 at 04:18, David Jencks <david_jencks@yahoo.com.
>>>> invalid>
>>>>> wrote:
>>>>> 
>>>>>> 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 <os...@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_jencks@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 <ap...@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
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>> 
>>>>>>> 
>>>>>> 
>>>>>> 
>>>> 
>>>> 
>> 
>> 


Re: [Converter] DTOs with methods?

Posted by David Bosschaert <da...@gmail.com>.
Hi David L,

The as() method (at least in its current incantation) say something about
how to treat the source object - the thing you are converting from. So in
your example
  myDtoWithMethods =
converter.convert(map).as(PlainDTO.class).to(DtoWithMethods.class)

it would try to treat the source map as a PlainDTO - which obviously will
fail.

I guess what you're looking for is a way to say: 'create a target object
from this class, but treat it as if it was that class', so maybe something
like this?:
  myDtoWithMethods =
converter.convert(map).to(PlainDTO.class).in(DtoWithMethods.class)

This is not yet implemented, it's just a suggestion. WDYT?

Cheers,

David

On 18 October 2016 at 11:27, David Leangen <os...@leangen.net> wrote:

>
> Hi David B.,
>
> Thanks for this suggestion. That would indeed work nicely. As you say, it
> requires an extra class, but at least there is very little duplication, at
> least converting TO something.
>
> Converting TO:
>
> >  Map m = converter.convert(myDtoWithMethods).as(PlainDTO.
> class).to(Map.class)
>
> When converting FROM something, would this work?
>
> myDtoWithMethods = converter.convert(map).as(PlainDTO.class).to(
> DtoWithMethods.class)
>
> If so, then I think this would work just fine!
>
>
> Cheers,
> =David
>
>
> > On Oct 18, 2016, at 6:13 PM, David Bosschaert <
> david.bosschaert@gmail.com> wrote:
> >
> > Hi David L,
> >
> > Recently I added the 'as()' method to the converter, which is really
> meant
> > to disambiguate source objects. Let's say you have an object that is
> both a
> > JavaBean as well as implementing an interface. The Converter spec will
> > specify some 'priority' rules for this, but they may not always be what
> you
> > want. The as() method can be used to treat the source object in a
> > particular way.
> >
> > For example, let's say your MyClass extends MyBean implements Intf1
> > Let's say you want to force the converter to look at an instance of
> MyClass
> > as Intf1.
> >
> > You could then do
> >  converter.convert(myobj).as(Intf1.class).to(Map.class)
> >
> > Would it help to use this for the DTO+methods as well?
> > You might have:
> >
> > Class PlainDto {
> >  public String foo;
> > }
> >
> > Class DtoWithMethods extends PlainDto {
> >  public int someMethod() {}
> > }
> >
> > And then maybe use these via:
> >  converter.convert(myDtoWithMethods).as(PlainDTO.class).to(Map.class)
> > ?
> >
> > It would require a separate class that follows the pure DTO rules...
> >
> > Cheers,
> >
> > David
> >
> >
> > On 18 October 2016 at 09:49, David Leangen <os...@leangen.net> wrote:
> >
> >>
> >> Hi David B.,
> >>
> >> Thanks. I think you’re right, the spec is quite clear.
> >>
> >> If I wanted to treat any class like a DTO (ignore the methods and use
> only
> >> the public fields — just like before the recent changes made to the code
> >> base), can you think of any way?
> >>
> >> Perhaps having “strict” mode to follow the spec to the letter, and a
> less
> >> strict mode for people like me?
> >>
> >>
> >> wdyt?
> >>
> >> Cheers,
> >> =David
> >>
> >>
> >>> On Oct 18, 2016, at 5:45 PM, David Bosschaert <
> >> david.bosschaert@gmail.com> wrote:
> >>>
> >>> Hi all,
> >>>
> >>> The OSGi spec for DTOs is pretty clear. Section 57.2 of the R6 Core
> spec
> >>> states:
> >>>
> >>> "Data Transfer Objects are public classes with no methods, other than
> the
> >>> compiler supplied default
> >>> constructor"
> >>>
> >>> Therefore I would be reluctant to use a different definition for the
> >>> Converter.
> >>>
> >>> OTOH I think that there are a couple of options if you like to have
> 'DTOs
> >>> with behaviour':
> >>> * you could use JavaBeans. The getters/setters are understood by the
> the
> >>> converter and will result in similar behaviour, but the beans can have
> >>> other methods too.
> >>> * registry your own converter rules for these classes.
> >>>
> >>> Cheers,
> >>>
> >>> David
> >>>
> >>> On 16 October 2016 at 04:18, David Jencks <david_jencks@yahoo.com.
> >> invalid>
> >>> wrote:
> >>>
> >>>> 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 <os...@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_jencks@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 <ap...@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
> >>>>>>>
> >>>>>>>
> >>>>>>
> >>>>>
> >>>>
> >>>>
> >>
> >>
>
>

Re: [Converter] DTOs with methods?

Posted by David Leangen <os...@leangen.net>.
Hi David B.,

Thanks for this suggestion. That would indeed work nicely. As you say, it requires an extra class, but at least there is very little duplication, at least converting TO something.

Converting TO:

>  Map m = converter.convert(myDtoWithMethods).as(PlainDTO.class).to(Map.class)

When converting FROM something, would this work?

myDtoWithMethods = converter.convert(map).as(PlainDTO.class).to(DtoWithMethods.class)

If so, then I think this would work just fine!


Cheers,
=David


> On Oct 18, 2016, at 6:13 PM, David Bosschaert <da...@gmail.com> wrote:
> 
> Hi David L,
> 
> Recently I added the 'as()' method to the converter, which is really meant
> to disambiguate source objects. Let's say you have an object that is both a
> JavaBean as well as implementing an interface. The Converter spec will
> specify some 'priority' rules for this, but they may not always be what you
> want. The as() method can be used to treat the source object in a
> particular way.
> 
> For example, let's say your MyClass extends MyBean implements Intf1
> Let's say you want to force the converter to look at an instance of MyClass
> as Intf1.
> 
> You could then do
>  converter.convert(myobj).as(Intf1.class).to(Map.class)
> 
> Would it help to use this for the DTO+methods as well?
> You might have:
> 
> Class PlainDto {
>  public String foo;
> }
> 
> Class DtoWithMethods extends PlainDto {
>  public int someMethod() {}
> }
> 
> And then maybe use these via:
>  converter.convert(myDtoWithMethods).as(PlainDTO.class).to(Map.class)
> ?
> 
> It would require a separate class that follows the pure DTO rules...
> 
> Cheers,
> 
> David
> 
> 
> On 18 October 2016 at 09:49, David Leangen <os...@leangen.net> wrote:
> 
>> 
>> Hi David B.,
>> 
>> Thanks. I think you’re right, the spec is quite clear.
>> 
>> If I wanted to treat any class like a DTO (ignore the methods and use only
>> the public fields — just like before the recent changes made to the code
>> base), can you think of any way?
>> 
>> Perhaps having “strict” mode to follow the spec to the letter, and a less
>> strict mode for people like me?
>> 
>> 
>> wdyt?
>> 
>> Cheers,
>> =David
>> 
>> 
>>> On Oct 18, 2016, at 5:45 PM, David Bosschaert <
>> david.bosschaert@gmail.com> wrote:
>>> 
>>> Hi all,
>>> 
>>> The OSGi spec for DTOs is pretty clear. Section 57.2 of the R6 Core spec
>>> states:
>>> 
>>> "Data Transfer Objects are public classes with no methods, other than the
>>> compiler supplied default
>>> constructor"
>>> 
>>> Therefore I would be reluctant to use a different definition for the
>>> Converter.
>>> 
>>> OTOH I think that there are a couple of options if you like to have 'DTOs
>>> with behaviour':
>>> * you could use JavaBeans. The getters/setters are understood by the the
>>> converter and will result in similar behaviour, but the beans can have
>>> other methods too.
>>> * registry your own converter rules for these classes.
>>> 
>>> Cheers,
>>> 
>>> David
>>> 
>>> On 16 October 2016 at 04:18, David Jencks <david_jencks@yahoo.com.
>> invalid>
>>> wrote:
>>> 
>>>> 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 <os...@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_jencks@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 <ap...@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
>>>>>>> 
>>>>>>> 
>>>>>> 
>>>>> 
>>>> 
>>>> 
>> 
>> 


Re: [Converter] DTOs with methods?

Posted by David Bosschaert <da...@gmail.com>.
Hi David L,

Recently I added the 'as()' method to the converter, which is really meant
to disambiguate source objects. Let's say you have an object that is both a
JavaBean as well as implementing an interface. The Converter spec will
specify some 'priority' rules for this, but they may not always be what you
want. The as() method can be used to treat the source object in a
particular way.

For example, let's say your MyClass extends MyBean implements Intf1
Let's say you want to force the converter to look at an instance of MyClass
as Intf1.

You could then do
  converter.convert(myobj).as(Intf1.class).to(Map.class)

Would it help to use this for the DTO+methods as well?
You might have:

Class PlainDto {
  public String foo;
}

Class DtoWithMethods extends PlainDto {
  public int someMethod() {}
}

And then maybe use these via:
  converter.convert(myDtoWithMethods).as(PlainDTO.class).to(Map.class)
?

It would require a separate class that follows the pure DTO rules...

Cheers,

David


On 18 October 2016 at 09:49, David Leangen <os...@leangen.net> wrote:

>
> Hi David B.,
>
> Thanks. I think you’re right, the spec is quite clear.
>
> If I wanted to treat any class like a DTO (ignore the methods and use only
> the public fields — just like before the recent changes made to the code
> base), can you think of any way?
>
> Perhaps having “strict” mode to follow the spec to the letter, and a less
> strict mode for people like me?
>
>
> wdyt?
>
> Cheers,
> =David
>
>
> > On Oct 18, 2016, at 5:45 PM, David Bosschaert <
> david.bosschaert@gmail.com> wrote:
> >
> > Hi all,
> >
> > The OSGi spec for DTOs is pretty clear. Section 57.2 of the R6 Core spec
> > states:
> >
> > "Data Transfer Objects are public classes with no methods, other than the
> > compiler supplied default
> > constructor"
> >
> > Therefore I would be reluctant to use a different definition for the
> > Converter.
> >
> > OTOH I think that there are a couple of options if you like to have 'DTOs
> > with behaviour':
> > * you could use JavaBeans. The getters/setters are understood by the the
> > converter and will result in similar behaviour, but the beans can have
> > other methods too.
> > * registry your own converter rules for these classes.
> >
> > Cheers,
> >
> > David
> >
> > On 16 October 2016 at 04:18, David Jencks <david_jencks@yahoo.com.
> invalid>
> > wrote:
> >
> >> 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 <os...@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_jencks@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 <ap...@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
> >>>>>
> >>>>>
> >>>>
> >>>
> >>
> >>
>
>

Re: [Converter] DTOs with methods?

Posted by David Leangen <os...@leangen.net>.
Hi David B.,

Thanks. I think you’re right, the spec is quite clear.

If I wanted to treat any class like a DTO (ignore the methods and use only the public fields — just like before the recent changes made to the code base), can you think of any way?

Perhaps having “strict” mode to follow the spec to the letter, and a less strict mode for people like me?


wdyt?

Cheers,
=David


> On Oct 18, 2016, at 5:45 PM, David Bosschaert <da...@gmail.com> wrote:
> 
> Hi all,
> 
> The OSGi spec for DTOs is pretty clear. Section 57.2 of the R6 Core spec
> states:
> 
> "Data Transfer Objects are public classes with no methods, other than the
> compiler supplied default
> constructor"
> 
> Therefore I would be reluctant to use a different definition for the
> Converter.
> 
> OTOH I think that there are a couple of options if you like to have 'DTOs
> with behaviour':
> * you could use JavaBeans. The getters/setters are understood by the the
> converter and will result in similar behaviour, but the beans can have
> other methods too.
> * registry your own converter rules for these classes.
> 
> Cheers,
> 
> David
> 
> On 16 October 2016 at 04:18, David Jencks <da...@yahoo.com.invalid>
> wrote:
> 
>> 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 <os...@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 <da...@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 <ap...@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
>>>>> 
>>>>> 
>>>> 
>>> 
>> 
>> 


Re: [Converter] DTOs with methods?

Posted by David Bosschaert <da...@gmail.com>.
Hi all,

The OSGi spec for DTOs is pretty clear. Section 57.2 of the R6 Core spec
states:

"Data Transfer Objects are public classes with no methods, other than the
compiler supplied default
constructor"

Therefore I would be reluctant to use a different definition for the
Converter.

OTOH I think that there are a couple of options if you like to have 'DTOs
with behaviour':
* you could use JavaBeans. The getters/setters are understood by the the
converter and will result in similar behaviour, but the beans can have
other methods too.
* registry your own converter rules for these classes.

Cheers,

David

On 16 October 2016 at 04:18, David Jencks <da...@yahoo.com.invalid>
wrote:

> 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 <os...@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 <da...@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 <ap...@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
> >>>
> >>>
> >>
> >
>
>

Re: [Converter] DTOs with methods?

Posted by David Jencks <da...@yahoo.com.INVALID>.
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 <os...@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 <da...@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 <ap...@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
>>> 
>>> 
>> 
> 


Re: [Converter] DTOs with methods?

Posted by David Leangen <os...@leangen.net>.
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 <da...@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 <ap...@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
>> 
>> 
> 


Re: [Converter] DTOs with methods?

Posted by David Jencks <da...@yahoo.com.INVALID>.
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 <ap...@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
> 
>