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
> >>>>>>>
> >>>>>>>
> >>>>>>
> >>>>>
> >>>>
> >>>>
> >>
> >>
>
>

Reply via email to