Куда ставить состояние приложения?
Где в коде лучше всего поместить создание объектов (объекты с состоянием), а где нет? В каких слоях?
Например, однажды я поместил ссылку на объект в класс DAO Hibernate, и мне сказали, что это неверно, поскольку классы DAO не должны иметь состояние. Состояние должно быть внутри "сервисного уровня".
Мне сказали, что я не должен создавать новые объекты при повторяющихся вызовах методов, таких как UpdateCart(). Создание объектов является дорогостоящим и не должно быть повсюду в вашем коде. Это должно быть только в методах инициализации. Например, если приложению электронной коммерции нужна корзина, поместите ее в сеанс. Если ему нужен какой-то общий главный объект, поместите его в код инициализации. Создайте его один раз и позвольте остальной части приложения получить доступ к его экземпляру позже. Не создавайте этот экземпляр при каждом вызове.
Я запутался в этом принципе дизайна. Самое странное, что я слышал, это то, что приложение не должно иметь состояния. Состояние должно храниться в слое данных, где находится база данных. В самом деле? Я совершенно новичок в этих концепциях дизайна, и я не знаю, где искать, чтобы получить больше информации об этом. GoF? Дизайн шаблонов книг? Цель состоит в том, чтобы создать качественный код (т.е. использовать в бизнесе).
Спасибо
2 ответа
Что является хорошей практикой, может варьироваться в зависимости от типа проекта.
Для большинства проектов создание объектов не так дорого для процессора. Стоимость, которая не всегда четко сформулирована, - это стоимость проекта. Похоже, что ваше приложение имеет методологию проектирования, в которой все состояние и объекты должны управляться контролируемым и централизованным образом. Это часто делается для улучшения ремонтопригодности и упрощения конструкции. Я не думаю, что вы просто должны знать, что это за дизайн, если он не был очень четко изложен вам.
Я подозреваю, что остальные члены команды привыкли работать определенным образом и не думают, что они должны документировать или обучать вас этой методологии, просто сказать вам, когда вы поняли это "неправильно". ИМХО это не продуктивно, но вам приходится иметь дело с ситуацией, которая у вас есть, и задавать им вопросы, когда дело доходит до размещения структур состояний или данных.
"приложение не должно иметь состояние. Состояние должно храниться в слое данных, где находится база данных
Есть проекты, где это является нормой, метко называемой "архитектура без гражданства". Независимо от того, должна ли каждая архитектура быть безгражданством, сомнительно, и сам термин, возможно, также открыт для обсуждения.
На самом деле, большинство "безгражданских" приложений действительно имеют состояние, но, как правило, указано выше (без каламбура), это состояние хранится в одном глобальном месте; база данных. Как упоминает Питер, причинами этого могут быть ремонтопригодность и упрощение, но также часто говорят, что это для scalability
, Если состояние не отображается нигде, кроме базы данных, считается, что легко добавить дополнительные интерфейсные серверы, серверы обработки и все, что у вас есть.
Хотя это действительно имеет некоторые достоинства, я думаю, что мы должны проводить различие между временным государством и авторитарным государством.
Временное состояние может быть чем-то вроде места, в котором вы находитесь в процессе заказа, и деталей, которые вы уже ввели. В Java EE вы можете сохранить это, например, в бинах @ConversationScoped или бинах @Stateful. Таким образом, это означает, что вы держите внутри веб-слоя, соответственно бизнес уровень.
Преимуществами этого являются простота использования, производительность и выгрузка единой центральной базы данных. Конечно, вы также можете хранить временное состояние в своей центральной базе данных, но вы, вероятно, хотите сохранить это в стороне от обычных, не временных данных, что означает, что требуется некоторая дополнительная сложность программирования. Кроме того, обычно гораздо быстрее извлекать данные из веб-слоя, и это снимает некоторую нагрузку с базы данных.
Во многих системах есть только одна основная база данных (база данных, принимающая записи), поэтому эта единственная база данных может стать огромным узким местом в этой установке.
В зависимости от вашей фактической архитектуры и настроек, сохранение временного состояния в базе данных может фактически улучшить вашу способность к масштабированию.
Недостатки в том, что вам нужно, чтобы ваш клиент придерживался единственного сервера, на котором в данный момент хранится временное состояние. Это типично называется "липкие сессии". Если один сервер, с которым взаимодействует этот клиент, выходит из строя или требует перезапуска или чего-то еще, клиент потеряет эти временные данные. Существуют некоторые схемы, такие как репликация состояния на все узлы кластера или соседние узлы (репликация собеседника), но это снова усложняет ситуацию и может привести к перегрузке сети (если все узлы постоянно реплицируются друг на друга).
Официальное состояние означает, что оно представляет общие данные, которые являются единственным источником информации. Этот тип состояния - то, что мы почти всегда хотели бы иметь в центральном местоположении, но иногда вы могли бы видеть, что оно хранится, например, в веб-узле.
Например, предположим, что у нас есть список последних цен, и вместо того, чтобы сохранять его в центральном местоположении, мы сохраняем его на веб-узле, где он был введен. Теперь существует концепция "одного-единственного" веб-узла, который имеет эту информацию, и другие серверы могут начать предполагать, что существует только этот "один-единственный" веб-узел. Добавление дополнительных узлов теперь невозможно, так как это нарушает это предположение.