Я разрабатываю простое веб-приложение. Я новичок в этом веб-домене. Мне нужен был ваш совет относительно шаблонов проектирования, таких как распределение ответственности между сервлетами, критерии создания нового сервлета и т. Д.
На самом деле, у меня есть несколько сущностей на моей домашней странице, и в соответствии с каждой из них у нас есть несколько вариантов, таких как добавление, редактирование и удаление. Ранее я использовал один сервлет для опций, таких как Servlet1 для добавления entity1, Servlet2 для редактирования entity1 и так далее, и таким образом мы получили большое количество сервлетов.
Сейчас мы меняем наш дизайн. Мой вопрос заключается в том, как именно вы выбираете, как вы выбираете ответственность сервлета. Если у нас есть один сервлет для каждой сущности, который обработает все его опции и перенаправит запрос на сервисный уровень. Или у нас должен быть один сервлет для всей страницы, который будет обрабатывать весь запрос страницы и затем перенаправлять его на соответствующий уровень обслуживания? Кроме того, должен ли объект запроса перенаправляться на сервисный уровень или нет.
источник
Ответы:
Немного приличное веб-приложение состоит из комбинации шаблонов дизайна. Я упомяну только самые важные.
Модель просмотра модели
Базовым (архитектурным) шаблоном проектирования, который вы хотели бы использовать, является шаблон Model-View-Controller . Контроллер должен быть представлен сервлета , который (в) непосредственно создает / использует конкретный модель и View на основе запроса. Модель должны быть представлены классами JavaBeans. Это часто делится на бизнес-модель, которая содержит действия (поведение) и модель данных, которая содержит данные (информацию). View должен быть представлен JSP файлы , которые имеют прямой доступ к ( Data ) Модель Е.Л. (Expression Language).
Затем существуют вариации, основанные на том, как обрабатываются действия и события. Популярные из них:
MVC, основанный на запросах (действиях) : это самый простой для реализации. ( Бизнес ) Модель работает непосредственно
HttpServletRequest
иHttpServletResponse
объекты. Вы должны собрать, преобразовать и проверить параметры запроса (в основном) самостоятельно. View может быть представлен простой ванили HTML / CSS / JS и не поддерживать состояние между запросами. Так работает Spring MVC , Struts и Stripes .MVC на основе компонентов : это сложнее реализовать. Но в итоге вы получаете более простую модель и представление, в которых весь «сырой» API сервлетов полностью абстрагируется. Вам не нужно собирать, преобразовывать и проверять параметры запроса самостоятельно. Контроллер выполняет эту задачу и устанавливает собранный, преобразованные и подтвержденные параметры запроса в модели . Все, что вам нужно сделать, это определить методы действия, которые работают непосредственно со свойствами модели. Вид представлен «компонент» в аромате JSP или библиотеки тегов XML элементов , которые , в свою очередь , генерирует HTML / CSS / JS. Состояние зрениядля последующих запросов сохраняется в сеансе. Это особенно полезно для событий преобразования, проверки и изменения на стороне сервера. Вот как среди прочего JSF , Wicket and Play! работает.
В качестве дополнительного примечания, хобби с использованием доморощенного MVC-фреймворка - очень хорошее упражнение для обучения, и я рекомендую его, если вы сохраняете его для личных / личных целей. Но как только вы станете профессионалом, тогда настоятельно рекомендуется выбрать существующий фреймворк, а не изобретать свой собственный. Изучение существующей и хорошо разработанной структуры занимает в долгосрочной перспективе меньше времени, чем разработка и поддержание надежной структуры самостоятельно.
В приведенном ниже подробном объяснении я ограничусь запросом MVC, поскольку его легче реализовать.
Шаблон переднего контроллера ( шаблон посредника )
Во-первых, часть Controller должна реализовывать шаблон Front Controller (который является специализированным типом шаблона Mediator ). Он должен состоять только из одного сервлета, который обеспечивает централизованную точку входа для всех запросов. Он должен создавать модель на основе информации, доступной по запросу, такой как pathinfo или servletpath, метод и / или конкретные параметры. Бизнес - модель называется
Action
в приведенном нижеHttpServlet
примере.Выполнение действия должно вернуть некоторый идентификатор, чтобы найти представление. Простейшим было бы использовать его в качестве имени файла JSP. Сопоставьте этот сервлет с конкретным
url-pattern
вweb.xml
, например/pages/*
,*.do
или даже просто*.html
.В случае префиксов-моделей , как, например ,
/pages/*
вы могли бы затем вызвать URL как http://example.com/pages/register , http://example.com/pages/login , и т.д. , и обеспечить/WEB-INF/register.jsp
,/WEB-INF/login.jsp
с соответствующим GET и POST действий , Деталиregister
иlogin
т. Д. Затем доступныrequest.getPathInfo()
как в примере выше.Когда вы используете суффикс-шаблоны, такие как
*.do
,*.html
и т. Д., Тогда вы можете вызывать URL-адреса, такие как http://example.com/register.do , http://example.com/login.do и т. Д., И вы должны изменить примеры кода в этом ответе (также theActionFactory
) для извлеченияregister
иlogin
частейrequest.getServletPath()
вместо.Стратегия
Action
Должны следовать шаблону стратегии . Он должен быть определен как абстрактный / интерфейсный тип, который должен выполнять работу на основе переданных аргументов абстрактного метода (в этом отличие от шаблона Command , в котором абстрактный / интерфейсный тип должен выполнять работу на основе аргументы, которые были переданы при создании реализации).Вы можете сделать
Exception
более конкретным с пользовательским исключением, какActionException
. Это просто базовый пример, остальное зависит только от вас.Вот пример того,
LoginAction
который (как следует из его названия) входит в систему пользователя. Само поUser
себе является моделью данных . View известно о присутствииUser
.Шаблон фабричного метода
ActionFactory
Должны следовать шаблону Фабричный метод . По сути, он должен предоставлять креационный метод, который возвращает конкретную реализацию абстрактного / интерфейсного типа. В этом случае он должен возвращать реализациюAction
интерфейса на основе информации, предоставленной запросом. Например, метод и pathinfo (pathinfo - это часть после пути контекста и сервлета в URL запроса, исключая строку запроса).В
actions
свою очередь, это должен быть статический объект / приложение,Map<String, Action>
которое содержит все известные действия. Это зависит от вас, как заполнить эту карту. жестко прописывать:Или настраивается на основе файла конфигурации свойств / XML в classpath: (псевдо)
Или динамически на основе сканирования в пути к классам для классов, реализующих определенный интерфейс и / или аннотацию: (псевдо)
Имейте в виду, чтобы создать «ничего не делать»
Action
для случая, когда нет отображения. Пусть, например, вернет непосредственноrequest.getPathInfo().substring(1)
тогда.Другие образцы
Это были важные образцы до сих пор.
Чтобы продвинуться дальше, вы можете использовать шаблон Facade для создания
Context
класса, который в свою очередь оборачивает объекты запроса и ответа и предлагает несколько удобных методов, делегирующих объектам запроса и ответа, иAction#execute()
вместо этого передает их в качестве аргумента в метод. Это добавляет дополнительный абстрактный слой, чтобы скрыть необработанный API сервлетов. Затем вы должны в итоге получить нулевыеimport javax.servlet.*
объявления в каждойAction
реализации. С точки зрения JSF, это то , чтоFacesContext
иExternalContext
классы делают. Вы можете найти конкретный пример в этом ответе .Затем есть шаблон State для случая, когда вы хотите добавить дополнительный уровень абстракции, чтобы разделить задачи сбора параметров запроса, их преобразования, проверки, обновления значений модели и выполнения действий. С точки зрения JSF, это то, что
LifeCycle
делает.Затем есть шаблон Composite для случая, когда вы хотите создать компонентное представление, которое может быть присоединено к модели и поведение которого зависит от состояния жизненного цикла на основе запроса. С точки зрения JSF, это то, что
UIComponent
представляют.Таким образом, вы можете постепенно развиваться в сторону компонентной структуры.
Смотрите также:
источник
web.xml
, то вы можете использоватьServletContextListener
для этого. Есть завод реализовать (и зарегистрируйтесь<listener>
вweb.xml
) и сделать работу наполнения во времяcontextInitialized()
метода.Action
реализации так же, как и с обычными сервлетами (см. Также вики-сервлеты для базового примера, который вы можете рефакторировать далее в некоторыйValidator
интерфейс). Но вы также можете сделать это до вызова действия, но это более сложно, так как требует, чтобы правила валидации были известны для каждого просмотра. JSF покрыла это, предлагаяrequired="true"
,validator="customValidatorName"
, и т.д. в XHTML - разметки.В взбитом паттерне MVC сервлет является "C" -контроллером.
Его основная задача - выполнить первоначальную оценку запроса, а затем отправить обработку на основе первоначальной оценки конкретному работнику. Одной из обязанностей работника может быть настройка некоторых компонентов уровня представления и перенаправление запроса на страницу JSP для визуализации HTML. Таким образом, только по этой причине вам необходимо передать объект запроса на сервисный уровень.
Я бы не стал писать сырые
Servlet
классы. Работа, которую они выполняют, очень предсказуема и типична, что очень хорошо делает эта структура. К счастью, есть много доступных, проверенных временем кандидатов (в алфавитном порядке): Apache Wicket , Java Server Faces , Spring и многие другие.источник
ИМХО, нет большой разницы в случае веб-приложения, если смотреть на него с точки зрения распределения ответственности. Однако сохраняйте четкость в слое. Сохраняйте что-либо исключительно для целей презентации на уровне представления, например элемент управления и код, специфичные для веб-элементов управления. Просто сохраните свои сущности на бизнес-уровне, а все функции (например, добавьте, измените, удалите) и т. Д. На бизнес-уровне. Однако рендеринг их в браузере должен обрабатываться на уровне представления. Для .Net шаблон ASP.NET MVC очень хорош с точки зрения разделения слоев. Посмотрите на шаблон MVC.
источник
Я использовал структуру Struts и нахожу ее довольно простой в изучении. При использовании структуры Struts каждая страница вашего сайта будет содержать следующие элементы.
1) Используемое действие вызывается каждый раз, когда обновляется HTML-страница. Действие должно заполнять данные в форме при первой загрузке страницы и обрабатывать взаимодействия между веб-интерфейсом пользователя и бизнес-уровнем. Если вы используете страницу jsp для изменения изменяемого объекта Java, копия объекта Java должна храниться в форме, а не в оригинале, чтобы исходные данные не изменялись, пока пользователь не сохранит страницу.
2) Форма, которая используется для передачи данных между действием и страницей jsp. Этот объект должен состоять из набора методов получения и установки атрибутов, которые должны быть доступны для файла JSP. Форма также имеет метод проверки данных до их сохранения.
3) JSP-страница, которая используется для отображения окончательного HTML-страницы. Страница jsp представляет собой гибрид HTML и специальных тегов Struts, используемых для доступа к данным в форме и манипулирования ими. Хотя Struts позволяет пользователям вставлять Java-код в JSP-файлы, вы должны быть очень осторожны с этим, потому что это делает ваш код более трудным для чтения. Java-код внутри jsp-файлов сложен для отладки и не может быть проверен модулем. Если вы обнаружите, что пишете более 4-5 строк кода Java внутри файла JSP, код, вероятно, следует перенести в действие.
источник
Отличный ответ BalusC охватывает большинство шаблонов для веб-приложений.
Некоторое приложение может потребовать Chain-of-liability_pattern
Вариант использования для использования этого шаблона:
Когда обработчик для обработки запроса (команда) неизвестен и этот запрос может быть отправлен нескольким объектам. Обычно вы устанавливаете преемник для объекта. Если текущий объект не может обработать запрос или обработать его частично и перенаправить тот же запрос к объекту- преемнику .
Полезные вопросы / статьи по SE:
Зачем мне использовать цепочку ответственности над декоратором?
Обычные способы использования цепи ответственности?
шаблон цепи ответственности от oodesign
chain_of_responsibility от создания источника
источник