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