0

I am not sure if this situation would more be related to generics than DTOs, but here it goes:

I have a DTO that represents a Person. A Person can have as children other Person(s) or just ResourceLink to those Person(s). This means that the child can be of either of the 2 types: Person (the DTO) or the ResourceLink. What type it would be, is determined through a queryParam and consequently logically through the flow follwed. I want to represent them using just ONE collection object and am not aware of the best way to do so.

Here is what I have so far:

public class PersonDTO<T> {

    @XmlElementWrapper(name = "children")
    @XmlElement(name = "child")
    List<T> children;
    // other stuff

}

With this approach, I need to define the translated type based on an if...else condition.

Earlier I had 2 different collections, one of which remained NULL. I also thought of extracting the relationship thing out in a new DTO as ChildrenDTO (not sure if that's a great idea)

I would like to know if there is a best practice for this situation, otherwise, if it is possible to declare a PersonDTO<PersonDTO> or PersonDTO<ResourceLink> depending on a condition.

Thanks in advance!

hkansal
  • 221
  • 5
  • 16

1 Answers1

1

I'd suggest instead, using a third type for the elements of List children:

    public interface PersonResolver () {
          Person resolvePerson ();
    }

    public class Person implements PersonResolver {
          Person resolvePerson () { return this; }
    }

    public class ResourceLink implements PersonResolver {
          Person resolvePerson () {
               if (myLinkTargetType == TARGET_TYPE_PERSON)
                      { return (Person) myTarget; }
               return null;
          }
    }
BRPocock
  • 13,638
  • 3
  • 31
  • 50
  • Pardon me for the late reply. Thanks for replying. Wouldn't this put two unrelated types in the same inheritance tree? Still, if a method is to return a Person, it would now be returning a PersonResolver, right? So it would have to be casted back to the required type for proper use, right? – hkansal Dec 29 '11 at 14:20
  • The idea here is, to store only PersonResolver types. A Person can then be resolved to itself (`Person a; a.resolvePerson() == a`), whereas your ResourceLink type would resolve to the person it links (`ResourceLink b; b.resolvePerson() == (Person)b.getTargetOfLink()`). — This allows the use of containers like `List` by allowing all of the children to yield a `Person` orthogonally, rather than `if (x instanceof Person)` and the like. As for “inheritance tree,” it's just an interface — it *makes* the types to be related; versus putting two unrelated types into a single container… – BRPocock Dec 29 '11 at 14:34
  • so a `Person` would have to have a PersonResolver, which could refer to either a `Person` or `ResourceLink` and we don't care what it is, as it'll be taken care of at runtime. I'm not happy with the *IsA* thing here, as I was looking for something more *HasA* types. But I'm thankful to you for taking time and answering. I'll mark it as accepted as I had, unfortunately, myself thought of an interface, without the resolver thing; but don't want to relate unrelated objects. Thanks! – hkansal Dec 29 '11 at 14:45