Как Вы организовали бы большое сложное веб-приложение (см. основной пример)?

Только, чтобы сохранить вещи интересными и закрыть мой заключительный нерешенный вопрос, решение, которое реализует ниже функциональности приятно организованным способом с достойной архитектурой, получает хорошую щедрость. Полный код находится на jsfiddle, и не стесняйтесь задавать любые вопросы :)

Как Вы обычно организуете сложные веб-приложения, которые чрезвычайно богаты на стороне клиента. Я создал изобретенный пример для указания на вид беды, в которая легко вовлечь, если вещами не управляют хорошо для больших приложений. Не стесняйтесь изменять/расширять этот пример, как Вы желаете - http://jsfiddle.net/NHyLC/1/

Пример в основном зеркально отражает часть регистрации комментария на и следует следующим правилам:

  1. Должен иметь 15 минимумов символов, после того, как несколько пробелов будут обрезаны одному.
  2. Если Add Comment нажат, но размер - меньше чем 15 после удаления нескольких пробелов, затем покажите всплывающее окно с ошибкой.
  3. Укажите на количество остающихся символов и подведите итог с цветовым кодированием. Gray указывает на маленький комментарий, коричневый указывает на средний комментарий, оранжевый большой комментарий, и красный переполнение комментария.
  4. Один комментарий может только отправляться каждые 15 секунд. Если комментарий отправлен слишком скоро, покажите всплывающее окно с соответствующим сообщением об ошибке.

Несколько проблем я заметил с этим примером.

  • Это должно идеально быть виджетом или своего рода упакованной функциональностью.
  • Вещи как комментарий в 15 секунд и минимальные 15 символьных комментариев принадлежат некоторому приложению широкие политики вместо того, чтобы быть встроенными в каждом виджете.
  • Слишком много трудно кодированных значений.
  • Никакая организация кода. Модель, Представления, Контроллеры все связываются вместе. Не то, чтобы MVC является единственным подходом для организации веб-приложений стороны толстого клиента, но в этом примере нет ни одного.

Как Вы пошли бы о чистке этого? Применение небольшого MVC/MVP по пути?

Вот некоторые соответствующие функции, но это будет иметь больше смысла, если Вы видели весь код jsfiddle:

/**
 * Handle comment change.
 * Update character count. 
 * Indicate progress
 */
function handleCommentUpdate(comment) {
    var status = $('.comment-status');

    status.text(getStatusText(comment));
    status.removeClass('mild spicy hot sizzling');
    status.addClass(getStatusClass(comment));
}

/**
 * Is the comment valid for submission
 * But first, check if it's all good.
 */
function commentSubmittable(comment) {
    var notTooSoon = !isTooSoon();
    var notEmpty = !isEmpty(comment);
    var hasEnoughCharacters = !isTooShort(comment);

    return notTooSoon && notEmpty && hasEnoughCharacters;
}

/**
 * Submit comment.
 * But first, check if it's all good!
 */
$('.add-comment').click(function() {
    var comment = $('.comment-box').val();

    // submit comment, fake ajax call
    if(commentSubmittable(comment)) {
        .. 
    }

    // show a popup if comment is mostly spaces
    if(isTooShort(comment)) {
        if(comment.length < 15) {
            // blink status message
        }
        else {
           popup("Comment must be at least 15 characters in length.");
        }
    }
    // show a popup is comment submitted too soon
    else if(isTooSoon()) {
        popup("Only 1 comment allowed per 15 seconds.");
    }

});

Редактирование 1:

@matpol спасибо за предложение для интерфейсного объекта и плагина. Это действительно будет большим улучшением по существующей путанице. Однако плагин весьма зависим и как я упомянул, это будет часть большего сложного приложения. Широкие политики приложения в отношении клиент-серверной стороны продиктовали бы вещи как минимальная/максимальная длина комментария, как часто может комментарий пользователя, и т.д. Конечно, плагин может питаться эта информация как параметры.

Кроме того, для приложения стороны толстого клиента данные должны были бы быть разделены от своего представления HTML, поскольку много распространений в прямом и обратном направлениях сервера могут быть сохранены, так как приложение осведомлено о данных, и вещи могли быть сохранены локально и периодически обновляться на сервере, или на интересные события в рамках самого приложения (такой как тогда, когда окно закрывается). Вот то, почему мне действительно не нравится сменный подход. Это работало бы, поскольку в обеспечивают упакованное представление, но это все еще центрировалось бы вокруг DOM, который будет проблематичным, когда у Вас есть 20 таких плагинов в приложении, которое не является абсурдным числом каким-либо образом.

17
задан Anurag 6 June 2010 в 22:30
поделиться

4 ответа

Я бы сделал это в 3 раза.

  1. Инкапсулируйте javascript в небольших четко определенных классах в пространствах имен
  2. Классы Javascript должны иметь HTML, который они требуют, «внедренный» в них в качестве зависимости, позволяющей модульное тестирование вне браузера.
  3. Перемещать как можно больше на стороне клиента функциональность сервера, насколько это возможно, и использовать концепцию, известную как AHAH

Javascript name-spacing

Этого можно легко добиться, и это было описано в других сообщениях, таких как этот Есть ли «краткий» способ сделать пространство имен в JavaScript?

Небольшие инкапсулированные классы

Код Javascript, как и код на стороне сервера, должен быть хорошо инкапсулирован с помощью небольших связанных классов и методов. Каждый класс находится в отдельном файле, названном вместе с пространством имен, в котором он находится, например: MyCompany.SomePackage.MyClass.js. Избыточные HTTP-запросы к каждому файлу можно сохранить с помощью объединения и минимизации этих файлов классов во время сборки.

Инверсия зависимостей в Javascript

Так эффективно вместо того, чтобы выбирать элементы, с которыми вам нужно работать внутри вашего класса, например:

var MyNamespace.MyClass = function() {
  var elementINeed = $('#IdOfElementINeed');
}

Вы бы внедрили это как таковое:

var foo = new MyNamspace.MyClass($('#IdOfElementINeed'));

var MyNamespace.MyClass = function(incomingDependency) {
  var elementINeed = incomingDependency;
}

Этот метод хорошо подходит для тестируемого javscript и разделение проблем посредством MVC-стиля слоев вашего кода.

AHAH и упрощение на стороне клиента

AHAH - довольно старый метод, который уже довольно давно используется в веб-разработке, хотя его чистая простота возрождается среди поклонников Интернета.Однако философия должна использоваться не только на уровне архитектурной техники, и она должна использоваться в качестве замены для всего вашего javascript на стороне клиента, например: проверка, отображение / скрытие динамического контента, вычисления и т. Д.

Где вы могли использовать прикрепил событие onClick со сложностью на стороне клиента:

$('#someElement').click(function(){
  // insert complex client-side functionality here, such as validating input
  // eg var isValid = $(this).val() < minimumCommentLength;
  // update page based on result of javascript code
  // eg $('#commentTooLong').show();
})

Теперь вы должны просто инициировать запрос ajax обратно на сервер, чтобы получить новый HTML и просто заменить все или некоторые элементы, которые вас интересуют как таковые:

$('#addCommentButton').click(function(){
  $.ajax({ 
    url: "/comment/add", 
    context: document.body, success: 
    function(responseHTML){
        $('body').html(reponseHTML);
      }});
})

Очевидно, это тривиальный пример, но при эффективном использовании ЛЮБОЕ событие javascript на странице просто запускает идентичный запрос ajax и замену HTML, значительно сокращая объем необходимого кода на стороне клиента. Перенос его на сервер, где он может быть эффективно протестирован.

Скорее всего, противники будут утверждать, что это неэффективный способ запуска веб-сайта, однако я использовал и видел эту технику на сайтах с доступом через модем 56k, а также на массово масштабируемых общедоступных веб-сайтах. Результат, конечно, медленнее, но вы все равно можете совершать круговые обходы менее 100 миллисекунд, что практически мгновенно для людей.

23
ответ дан 30 November 2019 в 12:27
поделиться

Я бы превратил его в плагин jQuery или статический объект.

Статический объект просто действует как вид или оболочка. Я бы также разбил его на более мелкие функции, например.

init()
checkLength()
checkTime()

Таким образом, вы можете получить что-то вроде:

Widget = {

init:function(){//setup events etc},
checkLength:function(){},
checkTime:function(){},
doMessage:function(){}


}
3
ответ дан 30 November 2019 в 12:27
поделиться

Matpol дал буквальное решение на конкретную предоставленную информацию. Ваша правка подразумевает, что вы ищете ответ на более гипотетический вопрос. Другими словами, вы ищете "подход".

Отвечая на вопрос таким образом; единственный пример, который вы привели, является немного красной селедкой. Это всего лишь один элемент в целом приложении, и он мешает нам "увидеть лес среди деревьев". Так что же такое лес? Вопрос, заданный как таковой, не определяет его. Но я думаю, что все программисты согласятся, когда я скажу, что это кошмар - работать над проектом, у которого нет определения. Поэтому я перефразирую ваш вопрос и отвечу: "Каков процесс определения проекта?"

Мой, на самом деле, состоит из серии вопросов:

  • Какова основная цель этого приложения?
  • Когда вы хотите его запустить? Если бы нам пришлось запустить его за 1/4 этого времени, какие функции вы бы сохранили?
  • Какие функции, вы абсолютно уверены, вам понадобятся после?

Во многих случаях, чтобы разобраться в этих вопросах, мне нужно задать другие бизнес-вопросы:

  • Кто ваша аудитория?
  • Почему им важен этот сайт? Что заставит их вернуться?
  • Как вы собираетесь генерировать доход?
  • Каков ваш призыв к действию? Если бы вы могли направить всех своих пользователей по одному пути, что бы это было?

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

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

4
ответ дан 30 November 2019 в 12:27
поделиться

Текущий код является хорошим началом, и его можно «масштабировать» в большие приложения, которые избегают жесткого кодирования и имеют четкое разделение MVC с помощью всего лишь нескольких изменений.

  • В идеале это должен быть виджет или какая-то упакованная функциональность.

Виджет упростит повторное использование функций комментариев и обеспечит их повторное использование на разных страницах / приложениях. Распространите инкапсуляцию и разделение проблем не только на презентацию, но и на модель виджета. Когда вы думаете о поле комментария, интуитивно понятно, что состояние компонента - это текст комментария, но все параметры, влияющие на его поведение, могут быть частью его модели, включая параметры проверки. Итак, в дополнение к тексту комментария я бы хотел, чтобы модель включала:

  • отображение количества символов в категорию размера (слишком маленький, маленький, средний, большой, переполнение).
  • максимальная частота отправки комментариев (15 секунд)

Модель виджета обновляет категорию размера по мере изменения текста. Представление прослушивает изменения в категории размера и значении категории размера, используемом для обновления класса текста для создания CSS-стиля для комментариев различной длины. Категория размера также проверяется при нажатии кнопки «Добавить комментарий». Если он «слишком мал» или «переполнен», может отображаться всплывающее окно. Обратите внимание, что обработчик добавления комментария не проверяет количество символов - которое изолировано в модели - он проверяет категорию размера. При необходимости контроллер «Добавить комментарий» может использовать то же сопоставление количества символов и категории размера, которое модель использует для создания полезных сообщений для пользователя. Например.«Комментарии должны содержать не менее 15 символов», где 15 выбирается из карты категорий размера.

Модель также предоставляет свойство «количество оставшихся символов», события изменения которого используются для обновления пользовательского интерфейса виджета. Максимальное количество символов выбирается из символа в карту категории размера.

  • Такие вещи, как комментарий каждые 15 секунд и минимум 15 символов комментария, относятся к некоторым политикам всего приложения, а не встраиваются в каждый виджет.
  • Слишком много жестко запрограммированных значений.
  • Нет кодовой организации. Модель, представления, контроллеры объединены вместе. Не то чтобы MVC - единственный подход для организации полнофункциональных клиентских веб-приложений, но в этом примере его нет.

Может быть много типов комментариев (например, разные комментируемые элементы) и разные типы комментариев-виджетов. Если все они должны иметь одинаковый минимальный / максимальный диапазон, тогда все они должны быть параметризованы одними и теми же модельными значениями, контролирующими проверку комментариев. Лучше всего это делать на стороне сервера при построении данных для модели комментариев. Текст комментария выбирается для этого конкретного комментария, а значения проверки комментария, такие как сопоставление размера и категории, выбираются из значений конфигурации страницы или приложения по умолчанию. Имея центральную логику для создания модели проверки компонентов, добавление новых правил становится намного проще - например, например, «модераторы могут оставлять комментарии до 1 КБ», становится изменением в одном фрагменте кода.Еще один момент, когда компонентная модель вычисляется на стороне сервера, заключается в том, что модель также должна проверяться на стороне сервера - проверка клиента - это скорее удобство для пользователя (некоторые могут подумать неудобство!) - а не жесткое принуждение. JavaScript может быть отключен, а HTTP-запросы созданы независимо от проверяющего клиента.

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

Я не упоминал jQuery или какие-либо технологии пользовательского интерфейса, поскольку этот шаблон действителен для приложений независимо от технологии пользовательского интерфейса. То, как вы применяете шаблон, будет в некоторой степени зависеть от пользовательского интерфейса, например, как модель проверки предоставляется виджету или как подключить слушателей к модели, но организационный уровень шаблона ортогонален пользовательскому интерфейсу. Основное внимание уделяется модели - расширению ее за счет включения аспектов проверки и вычислений на стороне сервера. Как только это будет сделано, проблема организации в значительной степени решена.

1
ответ дан 30 November 2019 в 12:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: