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.bosscha...@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 <o...@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.bosscha...@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 <o...@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.bosscha...@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_jen...@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 <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 >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>>> >>>> >>>> >> >>