LINUX.ORG.RU
Ответ на: комментарий от alex0x08

Но это всегда компромисс, либо долгая и сложная компиляция с валидацией либо часть ошибок будут в рантайме.

Но ведь авторы JSP могли сделать условно

<%@ page language="java" implements="InterfaceName" %>

Чтобы, например, при компиляции шаблона компилятор сразу бил по рукам, если мы пытаемся передать неитерируемый объект в <c:foreach items="">. Или при вызове неправильного шаблона из сервлета. Опять-таки, не пришлось бы передавать множество нетипизированных параметров через setParameter.

Я уже не говорю про скобки <% %>, которые позволяют засунуть в шаблон любой код, хоть запрос к БД, как здесь: https://www3.ntu.edu.sg/home/ehchua/programming/java/JSPByExample.html Это ж ничем от классических PHP bad practices не отличается.

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

Одно из ключевых отличий JSP и JSF как раз в этом моменте. JSP станица компилируется в сервлет либо при первом обращении либо заранее, а JSF - нет. В JSF прям жесткое разделение на шаблон и логику. Шаблон валидируется как XML, код лежит отдельно.

Между ними Expression Language (EL) - язык выражений, достаточно простой чтобы не быть проблемой.

Вообщем если не впадать в маразм и не насиловать инструмент, то вполне можно обходиться минимумом логики в шаблонах.

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

Опять-таки, managed bean выдёргивается тупо по имени, и какой у него интерфейс — абсолютно неизвестно до запуска страницы.

Но это что касается полноценных страниц. И на фронтенде в принципе со страницами тоже можно было сделать аналогично через тот или иной DI. А как быть с отдельными компонентами?

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

managed bean выдёргивается тупо по имени, и какой у него интерфейс — абсолютно неизвестно до запуска страницы.

Я ж говорю: без фанатизма.

Конечно же там куча ограничений, что класс этого бина должен быть публичным, его инстанциация должна происходить силами контейнера и еще много всякого.

Как только доходит до усложнения - пиши пропало. Поэтому простоту необходимо поддерживать всеми силами. Сложное сделать просто, простое - сложно.

Отдельные компоненты в JSF это тоже комбинация из шаблона и кода, с точно таким же разделением.

Но в рамках конечного проекта их обычно не делают, если только это не нечто монструозное.

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

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

vazgen05 ★★★
()
Ответ на: комментарий от alex0x08

Но в рамках конечного проекта их обычно не делают, если только это не нечто монструозное.

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

Кстати, а как в JSF делается родительский шаблон, который отвечает за общие части разных страниц?

static_lab ★★★★★
()
Ответ на: комментарий от vazgen05

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

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

Если смотреть от задачи, то окажется что не существует необходимости в постоянном изменении полей всегда и везде.

Форма->заполнение->отправка->отображение - как это было еще в 80х так и осталось сейчас для большинства бизнесового софта.

alex0x08 ★★★
()
Ответ на: комментарий от static_lab

Кстати, а как в JSF делается родительский шаблон, который отвечает за общие части разных страниц?

Наверное наиболее грамотным способом из всех виденных:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
                template="./template.xhtml">
 
    <ui:define name="top">
        Top Content
    </ui:define>
 
    <ui:define name="left">
        Sidebar Content
    </ui:define>
 
    <ui:define name="content">
        Main Content Goes Here!
    </ui:define>
 
    <ui:define name="bottom">
        Footer goes here
    </ui:define>
 
</ui:composition>

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

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
                template="./template.xhtml"
                xmlns:h="http://xmlns.jcp.org/jsf/html"
                xmlns="http://www.w3.org/1999/xhtml">
 
     
    <ui:define name="top">        
        Title : #{bean.title}
    </ui:define>
 
    <ui:define name="content">
        <h:form>            
            <h:panelGrid columns="2">
                <h:outputLabel value="First Name" class="label"/>            
                <h:inputText value="#{bean.person.firstName}"/>            
                <h:outputLabel value="Last Name" class="label"/>
                <h:inputText value="#{bean.person.lastName}"/>
                <h:outputLabel value="Customer Notes" class="label"/>                           
                <h:inputTextarea  value="#{bean.person.notes}"/>
            </h:panelGrid>
        </h:form>
    </ui:define>
 
    <ui:define name="bottom">
        Footer goes here
    </ui:define>
 
</ui:composition>
alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

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

Если смотреть от задачи, то окажется что не существует необходимости в постоянном изменении полей всегда и везде.

Суть в том, что компоненты Реакта не описывают только страницы, а для промежуточных компонентов строгая типизация — это хорошо. Точно так же, как строгая типизация в Java — это хорошо.

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

а для промежуточных компонентов строгая типизация — это хорошо

Вот это тоже смешной момент: получается что на бекэнде тенденция идет к отказу от строгой типизации в сторону duck typing и lazy evaluation, а на фронте ровно наоборот - идет переход от динамической к строгой.

Т.е ровно то за что на бекэнде не любят джаву - за это же на фронте обожают тайпскрипт.

Смешно.

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

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

static_lab ★★★★★
()
Последнее исправление: static_lab (всего исправлений: 1)
Ответ на: комментарий от static_lab

Я бы не сказал, что на бекенде прям тенденция.

В любом обсуждении Rust/Go/Elixir/Clojure/Scala и любой другой новомодный язык.

И разве есть повальное бегство с джавы/шарпа на динамическую типизацию в суровом энтерпрайзе?

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

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

alex0x08 ★★★
()
Ответ на: комментарий от static_lab

Ну вот например:

https://doc.rust-lang.org/book/ch19-04-advanced-types.html https://medium.com/journey-to-rust/my-first-insight-into-rust-type-system-601cdfd0b81f

Rust type system allows arbitrary amount of dynamic typing. If you want, you can write totally dynamic everything, and get all type errors in runtime (there is a dyn keyword for this).

Or, you can completely stop using any dynamic features and get all typechecking in a compile time.

Вообщем это опять такое современное «да но нет» или «вставить но на полшишечки».

Не хочу снова погружаться в обсуждение этих теологических вопросов, потому как сейчас опять набегут «идолопоклонники» и начнут всех поучать как правильно.

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

Вообщем это опять такое современное «да но нет» или «вставить но на полшишечки».

Ой, ну не за это же выбирают Раст для бекенда. В JVM и C# тоже есть поддержка динамической типизации, ну и что?

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

А что в ней необычного?

Ну как-то странно: фронт у тебя занимается вычислениями у кого какой выходной когда. ИМХО, фронт должен только взаимодействовать с пользователем, а логику и расчеты – в зад

pihter ★★★★★
()
Ответ на: комментарий от static_lab

Создание одного элемента в дереве требует собственно создания элемента через createElement, множества вызовов setAttribute, множества вызовов addEventListener, затем встраивания элемента в дерево.

Ну так оберни в удобный тебе способ. JS позволяет

Наконец, одна из важнейших фич: даже в WebComponents нельзя удобно делать динамические и быстрые for и if по элементам.

Ну когда создаешь – запоминай нужные тебе в массив. Или вообще как и что там тебе удобно

Мое недоумение только от того что кому-то мало того что предоставляет ЖС. Да делай что хочешь и при том никакой низкоуровневой запары. Ну да ладно: это, видимо, вкусовщина

pihter ★★★★★
()
Ответ на: комментарий от vvn_black

Есть документация с примерами, есть статьи на разных языках и для разной степени подготовленности аудитории.

По филологии тоже есть статьи, есть книги и форумы. От этого вопрос «объясни в двух словах зачем нужна Ё, когда уже есть ЙО» становится идиотским?

зачем нужен реакт

Декларативный подход к построению интерфейсов.

– почему в соборе святого Патрика звонят колокола?

– это как-то связано с религией!

pihter ★★★★★
()
Ответ на: комментарий от pihter

Мое недоумение только от того что кому-то мало того что предоставляет ЖС

Любой «велосипед» (в хорошем смысле слова) на JS рано или поздно доходит до состояния, когда:

  • пришла пора писать переиспользуемые компоненты
  • никуда не уйти от вложенных компонент
  • оказывается, что хорошо бы, чтобы у компонент было состояние, которым как-то надо управлять
  • каким-то образом надо в рамках приложения организовывать и глобальный стейт и обмен параметрами между компонентами
  • а тут ещё и вечный вопрос скрещивания ужа с ежом, верстки с стилями и кода, так, чтобы не было мучительно больно менять внешний вид компонент
  • еще, хочется чтобы код был чистым, а весь js в браузере это сплошные сайд-эффекты

Ну, вот, в частности реакт эти вопросы и разруливает.

vvn_black ★★★★★
()
Ответ на: комментарий от vvn_black

Ну, вот, в частности реакт эти вопросы и разруливает.

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

pihter ★★★★★
()
Ответ на: комментарий от pihter

Ну я приблизительно так и представляю

К чему тогда вопросы «объясни в двух словах зачем нужна Ё, когда уже есть ЙО»?

все в один голос твердят что в вебе без реакта и ему подобных жизни нет

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

vvn_black ★★★★★
()
Ответ на: комментарий от vvn_black

К чему тогда вопросы «объясни в двух словах зачем нужна Ё, когда уже есть ЙО»?

Да потому что никто и никогда не объяснил никак, кроме как общими фразами. Совсем общими, настолько общими – что они ко всему программированию применимы.

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

Ладно, молчу. Бог с ним, с вашим реактом. Спасибо за ответы

pihter ★★★★★
()
Ответ на: комментарий от alex0x08

Ага. И С++ тоже чисто динамический – ачотакова, можно же интерфейсы туда-сюда передавать, а то и вовсе std::any. Про void* вообще молчу.

Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 1)

Кто что думает о новой революционной технологии? Фронтенд теперь без js.

Всё новое - это хорошо забытое старое. Просто генерим html на сервере и отдаём клиенту. Всё.

«Нам эти ваши фронтенды, нафиг ненужны» ))

th3m3 ★★★★★
()
Ответ на: комментарий от pihter

В описанном ТЗ не предусматривается особых вычислений на клиенте. Автораскладка людей по дням может быть реализована и на бекенде. Но на фронте остаётся возможность отредактировать график.

static_lab ★★★★★
()
Ответ на: комментарий от pihter

Ну так оберни в удобный тебе способ. JS позволяет

Сначала написать тупую обёртку, затем решить, что в некоторых случаях пригодится и отложенный рендеринг компонента. Вот тебе и виртуальный DOM из React. Ведь его JSX-синтаксис — это на самом деле вызовы функций:

const UserInfo = ({name, jobTitle, avatar}) => (
  <div className="userinfo">
    <div className="userinfo__leading">
      <img className="userinfo__avatar" src={avatar} alt="name" />
    </div>
    <div className="userinfo__content">
      <div className="userinfo__name">{name}</div>
      <div className="userinfo__job">{jobTitle}</div>
    </div>
  </div>
);
const UserInfo = ({ name, jobTitle, avatar }) => (
  React.createElement("div", { className: "userinfo" },
    React.createElement("div", { className: "userinfo__leading" },
        React.createElement("img", { className: "userinfo__avatar", src: avatar, alt: "name" }),
    ),
    React.createElement("div", { className: "userinfo__content" },
        React.createElement("div", { className: "userinfo__name" }, name),
        React.createElement("div", { className: "userinfo__job" }, jobTitle),
    ),
  ),
);

Ну когда создаешь – запоминай нужные тебе в массив. Или вообще как и что там тебе удобно

Суть в том, что не стоит пересоздавать элементы в списке, если он уже созданы — это дорого, а нужно только добавить или удалить то, что изменилось. И для этого в самом JS есть только низкоуровневые appendChild и insertBefore. Например, можно сохранять массив ранее выведенных элементов, затем сравнивать его с новым и находить точки изменений. Будет та же самая реконсиляция, что и в React.

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

, а нужно только добавить или удалить то, что изменилось.

Тут можно нехило так выстрелить себе в ногу, поскольку нет простого способа понять состояние каждого элемента.

Может поменяться порядок элементов, может быть обновление отдельных полей, часть может исчезнуть, часть появиться - на уровне самих данных, полученных с сервера а не DOM элементов.

Поэтому временами логика «удалить все и заново сгенерировать список элементов» является оптимальной, пусть и не с точки зрения скорости то с точки зрения верифицируемости.

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

Тут можно нехило так выстрелить себе в ногу, поскольку нет простого способа понять состояние каждого элемента.

Ты же сам знаешь, как эти варианты решают фреймворки, в частности, React и Vue.

Поэтому временами логика «удалить все и заново сгенерировать список элементов» является оптимальной, пусть и не с точки зрения скорости то с точки зрения верифицируемости.

А если на компоненте для каких-то целей сделана обработка mount и unmount, то это будет ещё тяжелее.

static_lab ★★★★★
()
Последнее исправление: static_lab (всего исправлений: 1)
Ответ на: комментарий от static_lab

как эти варианты решают фреймворки, в частности, React и Vue

Нет, видимо ты из тех редких программистов, доживших до своего опыта, которых никогда в жизни сильно не били.

Представь что твоя зарплата зависит от рендера компонента на реакте - готов так подставиться?

Но полагаю этого мало, ладно. Представь что ты гражданин США и компонент на реакте будет решать сколько тебе придется платить по страховке в клинике: $5000 или $500000. Причем даже если произойдет ошибка - судиться с клиникой тебе не под силам - денег нехватит.

Готов сиграть в такую игру когда на кону собственное очко?

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

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

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

Вообще-то вопрос был другой и вполне конкретный, но твой ответ крайне показателен: даже зная что я не смогу создать условия для подобной проверки - ты до такой степени не веришь в собственный инструмент, что не готов подписаться под собственным решением даже виртуально.

Это все что вам нужно знать про Реакт в частности и MVVM концепцию в целом - это просто игрушка, с которой будут «играться», разумеется за ваш счет.

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

Я мало знаю о современном фронтенде и тем более о React, поэтому не совсем понимаю дискуссию. Но у меня вопрос: не мог бы ты развернуть мысль с примером про страховку? С твоей точки зрения неприемлемо то, что доменные правила приводятся в действие кодом на клиенте в принципе? Или проблема именно в React? То есть в составе React есть какой-то модуль/инструмент у которого проблемы с корректностью? Или у него недетерминированное поведение? Или поведение этого инструмента не было нормально формализовано?

asdpm
()
Ответ на: комментарий от asdpm

Попробую объяснить.

Реакт работает через события, те ты не можешь что-либо отобразить без отработки события. Помимо событий, в реакте есть биндинги полей: ты объявляешь набор полей, вставляешь их в шаблон а затем присваиваешь им значение - в этот момент отрабатывает проверка состояния и если фреймворк видит что поле поменялось - перестраивает DOM. Только после этого ты визуально на экране видишь изменения.

Это все упрощенно, в реальности все куда сложнее, особенно если знать что реакт работает не с реальной DOM моделью а со своей виртуальной - shadow DOM.

Отсюда получается что есть очень сложная логика с момента получения значения $5000 с сервера и до его отображения в браузере.

Поэтому для важных данных все также стараются показывать готовый html, сгенеренный на серверной стороне. Ну я стараюсь по крайней мере.

alex0x08 ★★★
()
Последнее исправление: alex0x08 (всего исправлений: 1)
Ответ на: комментарий от static_lab

А как ты себе это представляешь? Что я выдам 0day где вместо $5000 показывает ноль во всех случаях?

Это банальный инженерный подход - сокращение точек отказа. В инженерных ВУЗах такому учат.

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

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

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

Нет, речь лишь про сам контент, который легко валидируется. То что с сервера прилетело $5000 ты увидишь даже в логах nginx при желании.

Тут суть в том что убирается логика преобразования ответа сервера в представление на экране, чем и занимается реакт.

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

А браузер не занимается логикой преобразования ответа сервера в картинку?

И что мешает провалидировать условный JSON, который прилетает от сервера?

static_lab ★★★★★
()
Последнее исправление: static_lab (всего исправлений: 1)
Ответ на: комментарий от alex0x08

Не сильно стало яснее, но всё равно спасибо. Ну то есть он должен по изменениям в input сформировать и применить такой набор изменений, который переведет дерево то же состояние как если бы input изначально был таким. Твоя критика наводит на мысли, React это видимо какой-то полукривой типа дата-байндинг, который в силу каких-то объективных причин incomplete, поэтому некоторых гарантий дать не может. В результате сложность переместилась в ментальную область и вероятность ошибок возрастает.

asdpm
()
Ответ на: комментарий от static_lab

А браузер не занимается логикой преобразования ответа сервера в картинку?

Занимается. Но я и не говорил что браузер как средство отображения тоже стоит исключить (хотя так тоже делают, да)

И что мешает провалидировать условный JSON, который прилетает от сервера?

Это ничего не даст при ошибке на стадии отображения.

alex0x08 ★★★
()
Ответ на: комментарий от asdpm

Это все больше философский спор, из которого точно не стоит делать далеко идущие выводы.

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

Эту же тактику взяли на вооружение операторы большой тройки кстати.

alex0x08 ★★★
()
Ответ на: комментарий от static_lab

Однако можно протестировать сервер и клиент по-отдельности

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

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

Так и пользовательский браузер может легко «начудить», в том числе не в пользу клиента: https://output.jsbin.com/rewofotozi

Здесь нет ни «сложных», ни вообще каких-либо ошибок. Только эксплуатация вероятного окружения реального пользователя, у которого, скорее всего, стоит адблок.

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

Я не говорю что можно легко убрать все риски, лишь их сократить.

То что ты привел в пример - причина по которой до сих пор существуют клиентские программы и выделенные рабочие места.

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

Но клиентские программы тоже нужно писать, и это тоже большая точка отказа. Да и на практике получается, что с учётом зоопарка потенциальных клиентских платформ (Windows, Linux, macOS, Android, iOS) и бутылочного горлышка в виде необходимости обновлений клиентов, оказывается, что фронтенд в виде SPA-приложения и, дополнительно, мобильных приложений, — не так уж и плохо.

static_lab ★★★★★
()
Ответ на: комментарий от alex0x08

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

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

Я вот кстати уже больше полугода вяло воюю с техподдержкой своего банка, у которой из-за ошибки неправильно формируется строка моего адреса проживания. То есть в БД адрес корректен и разложен по разным полям, а бекенд формирует абсолютно кривую строку. При этом они каждый раз отвечают «Работы провели — ошибка исправлена». Так что даже без фронтенда простор для косяков остаётся огромный.

static_lab ★★★★★
()