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