Новости

Модальний підхід до розробки Web-додатків

  1. Все більше додатків взаємодіють з користувачем через браузер, що змушує пред'являти нові вимоги до...
  2. лексичні замикання
  3. продовження
  4. Реалізації модального підходу
  5. Переваги та недоліки модального підходу
  6. Наша реалізація
  7. перспективи
  8. література
  9. Технічні проблеми реалізації модального підходу
Все більше додатків взаємодіють з користувачем через браузер, що змушує пред'являти нові вимоги до протоколу HTTP. Він був розроблений для передачі і кешування статичних документів, тому концепції стану, клієнтських сесій, транзакцій, авторизації, багатоступеневих взаємодій в ньому відсутні або реалізовані недостатньо. Це зумовило виникнення безлічі технологій, зокрема методики створення Web-додатків за допомогою лексичних замикань і продовжень з серверної сторони.

Всесвітня павутина починалася як віртуальна мережа для поширення академічних публікацій, а сьогодні динамічні Web-додатки пристосовують її механізми для своїх потреб. Це стало джерелом ряду проблем, наприклад таких.

  • Гостьова книга. Її легко реалізувати у вигляді сторінок «перегляд записів» і «додавання записи», причому після додавання запису користувач потрапляє на сторінку перегляду. У запиті на додавання зазвичай використовується CGI, і новий запис передається в якості параметра сторінки «перегляд записів». Однак якщо користувач після додавання запису натисне в браузері кнопку Refresh (оновити), та ж запис буде додана вдруге.
  • Internet-магазини. Типова помилка - зберігати вміст «кошика» в прихованих полях форм або в прихованому фреймі. Здавалося б, якщо після оформлення замовлення натиснути кнопку Back (назад) браузера, то замовлення скасується (Back діє як Undo). Однак обидва способи «не працюють» в ситуації розгалуження сесії: якщо користувач відкриє якусь частину магазину в новому вікні і щось в ньому замовить, то на вмісті «кошика» в старому вікні це не відіб'ється. Інша помилка - зберігати вміст «кошика» на сервері короткий час, наприклад 20 хв з моменту останнього звернення. Якщо користувач відвернеться, він виявить, що всі його замовлення пропали.
  • Складне Web-додаток. Типова помилка - відстежувати стан авторизації і сесію по IP-адресою або за допомогою cookie. Додаток «зламається», якщо користувач має динамічним IP-адресою або його підмережа екранована одним IP-адресою, а підтримка cookie у клієнта може бути і зовсім відключена. Крім того, на одному комп'ютері часом працюють кілька користувачів. Інша поширена помилка - зберігати ключ сесії в прихованих полях форм і забути його вставити в одну з гіперпосилань або форм. Такої помилки складно уникнути, коли форм багато.

З цих прикладів видно - протоколу HTTP потрібні розширення, в тому числі для обслуговування спеціалізованих систем розробки Web-додатків (скажімо, ASP, JSP, PHP, Apache Cocoon, Seaside). Вони стикаються з ще більшою кількістю проблем, пов'язаних з масштабністю і розподілом навантаження, читаністю вихідного коду, розподілом обов'язків, обмеженістю обчислювальних ресурсів з серверної сторони, коректної роботою з «закладками» і забезпеченням безпеки. Крім того, характерною проблемою Web-інфраструктур є «інфляція відповідальності»: обрана система розробки Web-додатків нав'язує свої мову програмування, модель взаємодії з базами даних, метод опису інтерфейсів і т.д.

модальний підхід

Рушійна ідея модального підходу - організація коду Web-додатки не по окремих сторінках, а по шляхах взаємодії з користувачем. Наприклад, код, відповідний гіперпосиланням в HTML, є сусідами з кодом, який буде виконаний на сервері при переході по цьому посиланню. Сценарій, в якому користувач переходить послідовно від однієї сторінки до іншої (як wizard в MS Windows), буде описаний в коді Web-додатки лінійно і в одному файлі; розгалуження в сценарії будуть описуватися стандартними керуючими конструкціями (типу if або while). Такий ефект досягається завдяки використанню лексичних замикань і продовжень (в тих мовах програмування, де вони підтримуються) для зберігання стану клієнтської сесії. Назва «модальний підхід» (modal web development) запропонував Аві Брайант (Avi Bryant) за аналогією з «модальними діалоговими вікнами» в віконних інтерфейсах ( www.cincomsmalltalk.com/userblogs/ avi / blogView? showComments = true & entry = 3258414140 ).

лексичні замикання

Концепція «лексичних замикань» (lexical closures) досить стара. Вона бере початок в лямбда-численні, а вперше була реалізована в мові Lisp. Щоб зрозуміти, що таке замикання, можна розглянути наступний шматочок коду на мові Ruby:

x = 0
my_proc = lambda {x = 1}
print x # буде виведений 0

Лексичне замикання - це фрагмент програмного коду (анонімна функція), який може звертатися до лексичному контексту (локальних змінних і this) в точці свого створення, але існує окремо у вигляді об'єкта. У наведеному прикладі функція lambda перетворила операцію присвоєння {x = 1} в об'єкт, здатний «пережити» контекст, в якому він був створений.

У лексичних замикань багато застосувань, але нас цікавить їх використання в якості оброблювачів (callbacks). Ключова ідея полягає в тому, що програма здатна, наприклад, зв'язати з кожним гіперпосиланням обробник події переходу по ній, який буде мати доступ до контексту виконання на момент генерації вихідної HTML-сторінки. Таким чином, Web-додаток стає набором слабосвязанних скриптів, а повноцінною програмою. Одна сторінка може вільно передавати на іншу довільні об'єкти мови програмування, які іноді складно (або небезпечно) розміщувати в CGI-параметрах. Наприклад, створення посилання на сторінку оплати замовлення може виглядати так:

create_link ( «Purchase») {show_payment_page (shopping_cart)}

При цьому гіпотетичний об'єкт shopping_cart, доступний в лексичному контексті вирішення цієї сторінки, виявиться доступним і при виведенні наступної сторінки (після переходу за посиланням), хоча в явному вигляді він не зберігається і не передається від однієї сторінки до іншої. В цьому і полягає цінність лексичних замикань - у коду Web-додатки з'являється якийсь загальний контекст виконання, і тимчасові бар'єри між окремими сторінками стають прозорими.

продовження

«Продовження» (continuations) - також дуже стара концепція. Перша широко відома реалізація продовжень (call / cc) з'явилася в мові Scheme. Можна навести такий приклад Ruby-коду:

x = callcc {| cc | x = 2; cc.call (1)}
print x # надрукує 1

У ньому системна функція callcc створює об'єкт cc, до якого можна застосувати єдиний метод call. Коли цей метод викликається, перше звернення до функції callcc повертає значення. Таким чином, змінної x буде присвоєно значення 1, передане cc.call. Об'єкт cc можна, наприклад, зберегти, а пізніше викликати його метод call. Програма зробить «нелокальний стрибок» і продовжить своє виконання з моменту завершення функції callcc. Об'єкт cc, що має тип «продовження» (continuation), інкапсулює стан програми в певний момент (а саме - в момент виклику функції callcc), і згодом вона здатна повернутися до цього стану. Можна сказати, що функція callcc дозволяє визначати не тільки те, яке саме значення повернути, але і куди його повернути.

Цінність продовжень для Web-додатків полягає в тому, що вони дають можливість будувати взаємодію з користувачем лінійно - наприклад, «показати цю форму, потім, в залежності від введених значень, показати іншу, а потім ще одну». Для кожного етапу роботи програми на сервері можна зберігати об'єкт-продовження. При цьому не потрібно турбуватися про роботу кнопки Back в браузері, оскільки кожна показана користувачеві сторінка сама «знає», з якого «продовження продовжувати». Більш того, одну і ту ж ланцюжок діалогів можна відкрити в двох вікнах браузера і в кожному з них потроху просуватися, причому все буде працювати правильно. Лексичні замикання і продовження дозволяють, наприклад, реалізувати незвичайну для Web модель поведінки «виклик-повернення»:

create_link ( «Delete this file») {if (confirm ( «Are you sure?»)) delete (file)}

При натисканні на посилання Delete this file перед користувачем з'явиться сторінка, «питати» його, чи впевнений він у своєму рішенні. Вона є HTTP-аналогом модального діалогу. Коли користувач вибере ye »або no, функція confirm забезпечить повернення відповідного значення, і виконання обробника продовжиться. Реалізація цього за допомогою CGI була б на порядок складніше (наприклад, сторінці confirm потрібно було б «знати», про який саме дії питається).

Реалізації модального підходу

Вперше ідею застосування замикань і продовжень в Web-інтерфейси висунув в 1996 році Пол Грем, засновник фірми Viaweb. Ця ідея була використана їм у додатку Yahoo! Stores для створення Internet-магазинів. Зараз того додатка більше не існує, а його вихідний код був закритий. Відомо лише, що воно було повністю написано на Lisp і неправильно «обробляли» кнопку Back.

Наступні великі просування в цій області пішли з мов Scheme і Smalltalk. У комплект PLT Scheme (одній з середовищ розробки для Scheme, діалекту Lisp) входить програма Web Server (docs.plt-scheme.org/web-server/), яка дозволяє писати сервлети з використанням примітиву send / suspend ( «послати користувачеві сторінку, дочекатися відповіді і продовжити виконання »). Scheme виявився ідеальним мовою для реалізації подібних проектів. У деяких варіантах вдається навіть зберігати об'єкти-продовження на диску або обмінюватися ними по мережі, що неможливо ні в жодному іншому поширеному мовою програмування. Кнопка Back і розщеплення сесії в PLT Web Server працюють (URL кожної сторінки є ключем об'єкта-продовження на сервері), а закладки - немає, оскільки сервер видаляє старі об'єкти-продовження.

Проблема закладок взагалі не дуже добре досліджена. В одній з небагатьох робіт на цю тему [1] пропонується конвертувати в рядок дані про стан і відправляти її клієнту, уникаючи таким чином зберігання продовжень. Однак такий метод підходить далеко не для всіх мов програмування і до того ж не цілком прийнятний з точки зору інформаційної безпеки - клієнт може внести в рядок стану несанкціоновані зміни.

Щоб вирішити ці проблеми, Аві Брант реалізував проект IOWA на мові Ruby (enigo.com/projects/iowa/index.html), який потім перетворився в Seaside на Squeak Smalltalk (seaside.st). Середовище розробки Squeak ще більш незвичайна, ніж будь-яка Scheme-середовище. Наприклад, вихідний код в ній не зберігається в файлах, тому необхідно перевести на Squeak Smalltalk більшу частину програмного забезпечення. Разом з тим Seaside2, мабуть, - найефективніша на сьогоднішній день бібліотека для розробки Web-додатків.

Кожне Web-додаток в цьому середовищі є об'єктно-орієнтовану програму. Стан сесії - дерево об'єктів-компонентів. Будь-компонент вміє себе малювати і реєструвати обробники подій. Компоненти здатні на час делегувати обов'язки малювання інших компонентів (модель «виклик-повернення»). Кожен компонент може «зареєструватися», щоб по кнопці Back відкочувалося його стан (значення змінних екземпляра). Стан в Seaside зберігається на сервері, а клієнту через URL передаються лише ключі станів і продовжень. Завдяки цьому кнопка Back і розгалуження сесії практично завжди працюють правильно, але змусити вірно працювати закладки - досить складно. Ерік Ходель (Eric Hodel) перевів Seaside2 назад на мову Ruby, і закінчена версія отримала назву Borges (borges.rubyforge.org/). У проекті Apache Cocoon (cocoon.apache.org) діалект JavaScript, що підтримує продовження, використовується для опису інтерфейсів. А в проекті WDialog (wdialog.sourceforge.net) задіюється мову OCaml, який не підтримує продовжень і застосовує ідеї функціонального програмування фактично для їх емуляції.

Переваги та недоліки модального підходу

Модальний підхід дозволяє групувати логіку додатка за розділами оброблювачів і реакцій на дії користувача, а не по окремих сторінках. Також він забезпечує прозору підтримку сесії користувачів (через загальний контекст виконання для кожного споживача). Модальний підхід серйозно полегшує моделювання логіки взаємодії з користувачем, особливо якщо ця логіка складна. Аві Брант порівнює модальний підхід з добре відомим переходом від оператора GOTO (гіперпосилань) до структурного програмування (замикань і продовженням).

Однак далеко не всі мови програмування мають потрібні властивості, ідіома «закладок» не завжди працює, інтеграція з провідними HTTP-серверами (Apache і IIS) утруднена або неможлива, і практично кожен продукт нав'язує свою компонентну модель, середовище розробки, мова програмування і навіть мову опису інтерфейсів. Крім того, зберігання замикань і продовжень на сервері може вимагати набагато більших обчислювальних ресурсів, ніж при використанні CGI, а динамічно розподіляти навантаження між декількома серверами найчастіше неможливо або вкрай складно.

Недоліки модального підходу не обмежуються складнощами реалізації. Наприклад, Філіп Ебі (Phillip J. Eby) вважає: «Продовження мають таке ж відношення до Web-програмування, як функціональна декомпозиція до графічних інтерфейсів. На рівні користувача інтерфейсу це - погана ідея. Вона більш прийнятна для програмістів з лінійним мисленням »( discuss.fogcreek.com/ joelonsoftware / default.asp? cmd = show & ixPost = 94006 ). Дійсно, Web повинна давати користувачеві всі можливості контролювати ситуацію, а не перетворювати його в «периферійний пристрій, з якого зчитуються дані».

Цю думку поділяють багато послідовники REST-підходу [2] до написання Web-додатків. Основні особливості REST такі: прагнення до осмислених URL, відсутність зберігається на сервері стану сесії, використання кодів помилок HTTP на прикладному рівні, збереження семантики HTTP-методів GET і POST (відсутність побічних ефектів у GET і ідемпотентність POST).

Наша реалізація

Одна з причин, що спонукали нас задуматися про створення власної реалізації модельного підходу, - складність існуючих систем.

В Seaside / Borges (Smalltalk і Ruby) кожне Web-додаток представлено у вигляді набору компонентів, які можуть бути вкладені одна в одну. Сторінка виводиться шляхом малювання кореневого компонента. Використовуються концепції «фільтрації запитів» і «декорації компонентів». Є власна модель HTML-документів (через дерева лексичних замикань), висновок HTML-коду вручну ускладнено. Користувач повинен створювати класи компонентів для кожного завдання.

У WDialog (OCaml) інтерфейс сторінок описується у власному нестандартному XML-форматі, окремо від вихідного коду, а висновок HTML вручну неможливий.

В Apache Cocoon (JavaScript і різні діалекти HTML) фактично нав'язується певна модель архітектури додатку. Останнє розглядається як ланцюжок обробки XML-даних незалежними компонентами - «генераторами», «трансформерами» і «серіалізатор». Написати просте додаток на Cocoon, судячи з усього, не можна.

Наша реалізація модального підходу - це бібліотека Yo. Її вихідний код займає кілька кілобайт, а основна мета - додати до CGI нові можливості, не нав'язуючи розробнику додаткових архітектурних рішень.

На відміну від звичайного CGI (де кожен запит запускає новий інтерпретатор), в Yo вся робота здійснюється в рамках одного процесу, який може виділяти всередині себе окремі нитки (threads), що дозволяє швидше обробляти запити. Та ж ідея реалізується в модулях для Apache (типу mod_perl) і ISAPI. Це - загальне гідність практично всіх Web-бібліотек, що позиціонуються як альтернатива CGI.

При розробці, наприклад, гостьової книги для CGI-програміста було б природніше зробити окремі скрипти (файли) перегляду та додавання записи. Однак якщо ці скрипти мають якийсь загальний код (наприклад, таблицю стилів) і програміст виконає рефакторинг, то файлів стане вже три, а загальний код буде винесено в окремий файл. CGI-модель фактично нав'язує програмістові уявлення про те, як потрібно ділити Web-додаток на файли. Таке уявлення часто виявляється невірним. У свою чергу, багато зі згаданих високорівневих Web-бібліотек змушують програміста ділити свій код на компоненти, нав'язують власні модель розподілу повноважень, мова опису інтерфейсу і т.д. Бібліотека Yo дозволяє факторізовать функціональність так, як це зручно програмісту.

Web-додаток в Yo може зберігати глобальне стан в глобальних змінних. Так, при реалізації гостьової книги можна зберігати її вміст в масиві пам'яті, а час від часу створювати записи на диску нескладно. Крім того, через спільності контексту можна, наприклад, мати лише одне відкрите з'єднання з базою даних на всі додаток. Спільністю контексту характеризуються багато Web-бібліотеки, але ми спробували максимально полегшити роботу з контекстом (скажімо, не потрібно спеціально з'єднуватися з JavaBean, «об'єктом сесії»).

Бібліотека дозволяє при генерації будь-який HTML-сторінки зареєструвати обробник (створити лексичне замикання), отримати відповідний йому динамічний URL і створити на сторінці посилання на цей URL. При виконанні оброблювач одержує в якості аргументу набір пар «ключ-значення», переданих в якості CGI-змінних. Дана можливість - основна перевага всіх Web-бібліотек, заснованих на продовженнях.

Стандартну поведінку оброблювачів дій в Yo - відразу після виконання миттєво перенаправити користувача на будь-яку сторінку, URL якої не є автоматично згенерували. Таким чином, статичні URL в Yo відповідають даним, а динамічно згенеровані - діям. Ідея миттєвого перенаправлення була запозичена з бібліотеки Seaside2.

В принципі, можна було б писати додаток так само, як у всіх інших бібліотеках, заснованих на замиканнях і продовженнях: встановити одну фіксовану «точку входу» і зробити все внутрішні URL часовими. Однак за допомогою бібліотеки Yo можна писати і цілком стандартні CGI-додатки (набори сторінок, що посилаються один на друга), все URL в яких за замовчуванням залишаються активними необмежений час. Ті URL, які генеруються для обробників подій, все одно не будуть використовуватися в закладках, оскільки при переході по ним найчастіше миттєво відбувається redirect на один з «звичайних» URL. Таким чином, самі згенеровані URL ніколи не фігурують в адресному рядку браузера, і піклуватися про їх збереження не потрібно.

Поділ на «звичайні» і «динамічно згенеровані» URL - одна з ключових можливостей Yo при створенні Web-додатків в CGI-стилі, коли кожна посилання веде на деяку сторінку з даними. Якщо посилання пов'язані не з даними, а з виконанням деяких дій, можна реєструвати обробники. Закладки ж на сторінки будуть працювати завжди.

За замовчуванням в Yo після виконання обробника дії відбувається перенаправлення на вихідну сторінку, якщо обробник сам не «захотів» вивести будь-якої текст. В іншому випадку контекст всередині обробника дії нічим не відрізняється від контексту створення нової сторінки: в ньому можна виводити HTML, реєструвати нові обробники і т.д. Таким чином, вдається «зчепити» кілька сторінок в лінійну послідовність, всередині якої користувач не може ставити закладки - все URL автоматично генеруються і через деякий час пропадають.

Емуляція продовжень за допомогою ланцюжка лексичних замикань називається «CPS-перетворенням». Цей метод можна застосовувати в будь-якій мові програмування, в якому є лексичні замикання. Основна ідея полягає в тому, що кожен етап має бути окремим лексичним замиканням, в яке що аргументи передаються всі наступні (кожен етап «знає майбутнє» і передає його далі). Така методика краще, ніж використання продовжень в явному вигляді. Останнє має наступні недоліки:

  • воно захоплює весь стек, в тому числі контекст виконання різних функцій внизу стека, всередині Web-сервера, а це дорого, та й не потрібно;
  • продовження неочевидним чином взаємодіють зі «збирачем сміття»;
  • кожне продовження можна викликати лише з тієї ж нитки, в якій воно було створено (а замикання - звідки завгодно, тобто не потрібно створювати окрему нитку для кожної клієнтської сесії),
  • якщо момент завершення замикання чітко визначено, то продовження найчастіше необхідно явно передавати escape-продовження, щоб зупинити розмотування стека;
  • дуже складна налагодження програм, явно використовують продовження (особливо пошук витоків пам'яті).

Коли користувач закінчує рух по ланцюжку динамічних сторінок, він може вийти на одну зі звичайних сторінок (за посиланням або перенаправлення).

перспективи

Бібліотека Yo ( yo-lib.rubyforge.org ) Написана на мові Ruby і поки ще нав'язує вибір Web-сервера (WEBRick), котрі дають доступу до багатьох важливих об'єктів (наприклад, HTTP-заголовками). Це ускладнює її застосування в промислових додатках. Разом з тим вихідний код її реалізації досить компактний і не використовує продовження. А тому переклад Yo на будь-яку мову програмування, що підтримує в якомусь вигляді лексичні замикання (Perl, Smalltalk, Lisp, Java з анонімними класами), проблем не викликає. Ймовірно, з метою практичного застосування бібліотеки потрібно переписати її на Perl / FastCGI і створити ISAPI-модуль або Java-сервлет. Однак в даному випадку вибір технології та особливості реалізації будуть диктуватися комерційними, а не дослідними інтересами.

література
  1. Paul Graunke, Robert Findler, Shriram Krishnamurthi, Matthias Felleisen. Automatically Restructuring Programs for the Web. // Automated Software Engineering. 2001.
  2. Roy T. Fielding. Architectural Styles and the Design of Network-based Software Architectures. // PhD Thesis. University of California, Irvine, 2000..

Володимир Слепнев ( [email protected] ) - молодший науковий співробітник НДІ механіки МГУ (Москва).

Технічні проблеми реалізації модального підходу

Прибирання сміття

У Web-додатках, що використовують лексичні замикання і продовження, проблема пам'яті виходить на перший план. Лексичне замикання не дає «збирачеві сміття» знищити об'єкти, до яких можна звернутися з контексту замикання. Якщо кілька замикань посилаються один на одного, утворюючи ланцюжок, то Web-додаток з кожним зверненням захоплює все більше і більше пам'яті.

Замикання рідко виявляються причиною таких проблем, оскільки «бачать» лише безпосередній контекст виконання (лексичні змінні верхньої функції стека в момент створення). Але коли з'являються продовження, виникають складності: продовження захоплює повний контекст виконання в момент створення (лексичні змінні всіх функцій в стеці викликів). Якщо десь в стеці була можливість звернутися до іншого продовження, то і воно буде виключено з процесу «збирання сміття», а крім того, будуть охоплені ще якісь контексти, продовження і т.д. Подібні помилки вкрай важко виявити за допомогою автоматичних тестів, і ще важче знайти їх причину. Нарешті, коли в програмі використовуються продовження, виникають деякі специфічні проблеми, які природно вирішувати також за допомогою продовжень (наприклад, escape continuations).

відкат

Такі середовища, як Seaside2, зручні для створення і налагодження Web-додатків. Вони підтримують стійку ілюзію, ніби показується користувачеві Web-сторінка є зображенням дерева об'єктів, існуючого на сервері. Ця метафора дуже корисна (наприклад, можна прямо в браузері редагувати зовнішній вигляд окремих компонентів сторінки і відразу ж бачити зміни), але підтримувати її складно. Одна з проблем - відкат, «перемотування» назад. По ходу роботи програма здатна створювати екземпляри компонентів, що мають внутрішній стан. Пізніше ці екземпляри можуть стати непотрібними і піддатися процедурі «збирання сміття». Але для того, щоб «відмотувати» назад стан компонентів при натисканні кнопки Back, система повинна знати, які саме компоненти «відмотувати». Для цього необхідний якийсь список, але він містить посилання на старі компоненти і, отже, заважає правильній "збірці сміття».

Одне з рішень - використовувати «слабкі» посилання (weak references), які не впливають на «збірку сміття». Правда, вони можуть несподіваним чином взаємодіяти з лексичними замиканнями і продовженнями. Ця проблема часто виникає у користувачів Seaside і Borges. Крім того, якщо для вирішення проблеми потрібно задіяти «слабкі» посилання (і взагалі object identity), то її постановка, швидше за все, невірна.

Закладки

Проблема «перемотування» назад з'являється через те, що деяка частина стану системи принципово не може (або не повинна) виноситися на сторону клієнта. Наприклад, передавати лексичні замикання через URL дуже складно, а об'єкти-продовження, судячи з усього, - взагалі неможливо. Через це у багатьох реалізаціях стан зберігається на сервері, а клієнт отримує лише «ключ» стану. Природно, при «складанні сміття» серверне стан може зникнути. До того ж замикання і продовження - досить «важкі» об'єкти (за вимогами до пам'яті і обчислювальних ресурсів), і, коли клієнтів багато, зберігати більше десятка старих станів для кожного з них стає складно.

В Seaside запропонований такий механізм: додаток може відправити довільну інформацію в URL (разом з ключем стану), але відповідальність за її подальше вилучення також лягає на додаток. Змусити таким способом Seaside- або Borges-додаток правильно працювати з закладками складно, проте в інших Web-системах, заснованих на продовженнях, така можливість і зовсім не розглядається.

приховане стан

Проблема «прихованого стану» є типовою для систем, заснованих на продовженнях. Користувачі звикли до того, що сторінка повністю відображає поточний стан діалогу, проте в системі, заснованої на продовженнях, це часто не так. Наприклад, сторінка підтвердження може «не знати», яка саме дія вона підтверджує. Якщо кілька компонентів розташовані на різних закладках, то стан невидимих ​​компонентів «незримо присутній», хоч їх і не видно на екрані.

Добре це чи погано - питання складне. Найбільша проблема виникає в ситуації «невидимого стека», коли одна сторінка викликає функцію, малює іншу сторінку, яка, в свою чергу, малює третю і т.д. При цьому кожна сторінка зберігає продовження, і кожне продовження зберігає посилання на попереднє ( «стек викликів»), через що займана пам'ять зростає з кожним запитом. Проблема полягає в тому, що писати подібний код в системах, заснованих на продовженнях, дуже легко, а навчити новачка бачити такі помилки в коді - дуже складно.

Com/userblogs/ avi / blogView?
«Are you sure?
Asp?

Уважаемые партнеры, если Вас заинтересовала наша продукция, мы готовы с Вами сотрудничать. Вам необходимо заполнить эту форму и отправить нам. Наши менеджеры в оперативном режиме обработают Вашу заявку, свяжутся с Вами и ответят на все интересующее Вас вопросы.

Или позвоните нам по телефонам: (048) 823-25-64

Организация (обязательно) *

Адрес доставки

Объем

Как с вами связаться:

Имя

Телефон (обязательно) *

Мобильный телефон

Ваш E-Mail

Дополнительная информация: