Термин «состояние» в этом контексте немного вводит в заблуждение. Он ссылается на диалоговое состояние , означающее, что если клиент делает несколько вызовов, сессионный компонент не может узнать об этом. Представьте себе последовательность звонков:
reserveSeatsOnFlight()
;
chooseMealPreference()
;
confirmBooking()
.
Имеется диалоговое состояние, означающее, что второй вызов должен быть выполнен для того же компонента, что и первый вызов, иначе это просто не будет иметь смысла. Это то, что делают сессионные компоненты с состоянием.
Сессионные компоненты без сохранения состояния могут иметь переменные экземпляра, но они по сути глобальные. Если у вас есть пул сессионных компонентов без сохранения состояния (что вы можете или не можете, в зависимости от того, что решит делать контейнер), переменные этих экземпляров могут существовать или не существовать от одного вызова к другому. Поэтому обычно избегайте переменных экземпляра. Есть и другие механизмы для такого рода вещей.
Позвольте мне привести вам пример. Представьте себе этот вызов в сеансе без состояния:
public void bookFlight(List<Passsenger> passengers, FlightNumber flight, Date date) {
...
}
если вы введете переменную экземпляра для подсчета количества бронирований и увеличения ее при каждом вызове, то последующие вызовы могут вызывать разные компоненты, поэтому будут отображаться разные значения. Вот что я имею в виду, и это не обязательно имеет смысл.
Итак, возвращаясь к первому примеру, один из способов справиться с этим - передать состояние вызывающей стороне:
public interface ReservationSystem {
public int createNewBooking();
public int reserveSeatsOnFlight(int bookingId, int seats);
public int chooseMealPreference(int bookingId, ...)
...
}
Видите, как вышеупомянутое больше не имеет разговорного состояния? Ну, это так, но теперь оно заключено в bookingId
, который вы передаете. Сессионный компонент без сохранения состояния может получить бронирование и продолжить с того места, где остановился другой.