Подтвердить что ты не робот

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

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

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

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

  • Должно быть минимум 15 символов, после того, как несколько мест обрезаны к одному.
  • Если нажата кнопка Add Comment, но размер меньше 15 после удаления несколько пробелов, затем показать всплывающее окно с ошибкой.
  • Укажите количество оставшихся символов и суммировать с цветовым кодированием. Серый указывает на небольшой комментарий, коричневый цвет указывает на средний комментарий, оранжевый большой комментарий и красное переполнение комментариев.
  • Один комментарий может быть представлен только каждые 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 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 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 таких плагинов в приложении, что не является абсурдным числом любыми способами.

4b9b3361

Ответ 1

Способ, которым я буду делать это, в 3 раза.

  • Инкапсулировать javascript в маленьких четко определенных классах в пространствах имен
  • Классы Javascript должны иметь HTML-код, который им требуется "вводить" в качестве зависимости, позволяя тестировать модуль без браузера.
  • Переместите как можно больше клиентских функций на сервер и используйте концепцию, известную как 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, что значительно сокращает количество требуемого кода на стороне клиента. Перемещение его на сервер, где он может быть эффективно протестирован.

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

Ответ 2

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

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

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

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

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

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

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

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

Ответ 3

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

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

init()
checkLength()
checkTime()

Итак, у вас может получиться что-то вроде:

Widget = {

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


}

Ответ 4

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

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

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

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

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

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

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

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

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

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