Я думаю, что вам нужно реализовать так называемый шаблон «Преобразователь данных».
Представьте, что у вас есть сценарий использования, который возвращает определенный объект домена (например, «Пользователь»), но вы не должны предоставлять домен клиентам. И вы хотите, чтобы каждый клиент выбирал формат возвращаемых данных.
Итак, вы определяете интерфейс преобразователя данных для объекта домена:
public interface UserDataTransformer {
public void write ( User user );
public String read();
}
Для каждого выходного формата вашим клиентам необходимо определить класс, реализующий интерфейс. Например, если вы хотите представить пользователя в формате XML:
public class UserXMLDataTransformer implements UserDataTransformer {
private String xmlUser;
@Override
public void write(User user) {
this.xmlUser = xmlEncode ( user );
}
private String xmlEncode(User user) {
String xml = << transform user to xml format >>;
return xml;
}
@Override
public String read() {
return this.xmlUser;
}
}
Тогда вы делаете свою прикладную службу зависимой от интерфейса trasnsformer данных, вы вставляете его в конструктор:
public class UserApplicationService {
private UserDataTransformer userDataTransformer;
public UserApplicationService ( UserDataTransformer userDataTransformer ) {
this.userDataTransformer = userDataTransformer;
}
public void myUseCase ( Command c ) {
User user = << call the business logic of the domain and construct the user object you wanna return >> ;
this.userDataTransformer.write(user);
}
}
И, наконец, клиент может выглядеть примерно так:
public class XMLClient {
public static void main ( String[] args ) {
UserDataTransformer userDataTransformer = new UserXMLDataTransformer();
UserApplicationService userService = new UserApplicationService(userDataTransformer);
Command c = << data input needed by the use case >>;
userService.myUseCase(c);
String xmlUser = userDataTransformer.read();
System.out.println(xmlUser);
}
}
Я считаю, что выводом является строка, но вы можете использовать обобщенные значения, возможно, для возврата любого типа, который вы хотите.
Я не упомянул об этом, но этот подход при внедрении преобразователя в службу приложения следует шаблону «порт и адаптеры». Интерфейс преобразователя будет портом, а каждый реализующий его класс будет адаптером для нужного формата.
Кроме того, это был только пример. Вы можете использовать инфраструктуру внедрения зависимостей, такую как Spring, чтобы создавать экземпляры компонентов и связывать их все. А также вы должны использовать корневой шаблон композиции, чтобы сделать это.
Надеюсь, этот пример помог.