we are implementing a system with Strategy pattern.
Some callers to a specific methods require a Hashmap of data while in some case it would be a user-defined DTO. Some need both.
How do we decide which return type to use, instead of an Arraylist containing Hashmap and DTO ? Is there anything more approporiate?
Example:
Some caller needs only 2 strings and prefers a Hashmap.
Some other caller to the same API needs 12 values which are suited to put in a DTO. 1st caller does not need all the elements in the DTO.
3rd caller needs all 14 values and hence both structures.
If some callers require
Map(BTW don’t use concrete types likeHashMapin your interfaces) and others an object, there might be two reasons for that:the method returns completely different things depending on the arguments (e.g. if the flag is set, return a map of privileges whereas if it’s not, return object representing user himself)
you are returning different view of the same entity
In the first case your interface is seriously flawed and should be redesigned. Probably you need two methods performing different tasks. What do you mean by “different callers“? Depending on who calls the method, you decide what to return?
In the second case think of a more general model and return it. Then let the clients transform it to appropriate format. There are several ways to do this:
return format-agnostic type and provide methods converting to map and to object so the client can decide. For instance if you are not sure whether the client prefers weakly-typed map with properties or strongly-typed object having the same attributes/fields, return simple wrapper having
toMapandtoObjectmethods. Note that in this case the internal representation is not important, client always uses a view and you can always add new format in the futurereturn generic
Modelclass having two subclasses:MapModelandObjectModel, exposing appropriate getters in subclasses. Do not useinstanceofbut Visitor pattern instead. In this model you always return a single value and the client has to be able to deal with every format. If you add a new format (likeXmlModel), all the places whereModelis used need to be customized to deal with new type. However in this scenario you don’t need to transform the internal representation to different formats.Note that returning an
Objector any variation of that is simply landing in dynamic languages land where you no longer have any static-typing help.