2012-12-03 3 views
0

Это проблема дизайна/шаблонов. У меня есть услуга, которая теперь также нуждается в , которая будет показана как веб-служба RESTful.Дизайн: обеспечение чистого разделения рендеринга ответа от ответа

Внутри существующего кода у меня есть концепция запроса, набор возможных сервисов ServiceOperations (стратегии) ​​и возврат любого ServiceOperation - это объект Response. Этот подход отделяет внутреннюю работу службы от среды презентации (пользовательский TCP-сервер, HTTP REST, HTTP SOAP и т. Д.).

Я теперь начал реализовывать MyServiceRESTfulServlet, который выглядит примерно так:

public void doGet(HttpRequest httpRequest, HttpResponse httpResponse) throws ServletException, IOException { 
    try { 
     /* Wrap an http servlet request with an adapter which hides all 
     * the messy details of an HttpRequest and exposes a nice interface 
     * for working with MyService 
     */ 
     IRequest serviceRequest = new MyServiceRESTfulRequest(httpRequest); 

     /* There's nothing HTTP related in this part, it's the exact same 
     * code you'd find in other presentation formats. A Response has 
     * no idea about HTTP, TCP Servers or the like. 
     */ 
     Response serviceResponse = dispatchRequest(serviceRequest); 

     /* A static helper which knows the interface of a Response 
     * and can translate that into REST-speak for feeding back via 
     * an HttpServletResponse. 
     */ 
     renderRESTfulResponse(serviceResponse, httpResponse); 
    } catch (Exception e) { 
     throw new ServletExcetion(e); // Caught by a seperate 
             // RESTfulErrorServlet 
             // configured in web.xml 
             // Rendering an appropriate 
             // response. 
    } 
} 

Моя проблема заключается в ответ может быть один из 2-х видов в настоящее время:

public enum ResponseKind() { 
    BINARY, METADATA; 
} 

Для двоичном, мой вспомогательный помощник поможет сделать один способ, для метаданных ему понадобятся соответствующие метаданные - таблица HTML, блок JSON и т. д.

Выяснить, какой тип легко - объект Response выставляет getOriginalRequest(), который после соответствующих проверок могут быть поданы к MyServiceRESTfulRequest, который выставляет .getAcceptablePresentation() - в перечисление:

public enum RESTPresentationKind() { 
    HTML, JSON, XML, PROTOBUF_MYSERV_0.1; 
} 

Как лучше всего, я могу сохранить этот код рендеринга от объекта Response. В будущем, без сомнения, возможны другие варианты ответа. Как есть, renderRESTfulResponse() отправляется на рейд через объект Request и строит , выписывая данные соответствующим образом. Он очень плотно связан как с интерфейсом отклика (с которым я в порядке), но он знает, что он тоже проталкивает объект .

Я просто не чувствую, что я сделал этот бит как чистый и поддерживаемый способ , так как у меня остальная часть этого сервиса. Я «специальный корпус» для каждого из возможных типов ответов и каждый из возможных форматов ответа. Ощущается uber-hacky.

Можете ли вы предложить какой-либо способ для чисто обработки рендеринга ответа RESTful с учетом объекта-агностика запроса?

ответ

0

Почему бы не реализовать рендеринг на вашем перечислении RepsonseKind (перечисления действительно классы) или обойтись без ity? Когда вы пытаетесь избавиться от операторов case/switch, ответ обычно представляет собой либо композицию + перегрузку + шаблон команды, либо шаблон посетителя.

+0

ResponseKind тогда будет иметь багаж об HTTP REST, но это не имеет смысла, когда оно используется в контексте TCP-сервера. Шаблон посетителя выглядит интересным. – CraigJPerry

+0

Просто у ResponseKind реализовано несколько интерфейсов. Или он выдаст экземпляр типа, который будет обрабатывать обработку, за вычетом багажа HTTP/REST. Последний был бы более «единодушным». –

Смежные вопросы