То есть вместо получения машиночитаемых результатов поиска, мы получаем с сервера их готовое представление в виде кода на HTML
Это очень хорошая идея но ровно до того момента когда появится интерактивность внутри этого представления.
В этом примере подразумевается, что SearchBox не содержит вообще никакой другой логики, кроме отсылки на сервер событий, с ним произошедших (действий пользователя или разработчика) и показа присланного с сервера контента.
Решив проблему с универсальным UI на каждых чих приезжающий с сервера возникнет совсем другой класс проблем. Сетевых проблем, результатом которых будет либо недогруженный UI или несоответствие версий UI, измененные пути ведущие в 404 и т.п.
Тем не менее, мы не можем не отметить: при том, что любая крупная IT-компания проходит через эту фазу — разработки Backend-Driven UI (они же — «тонкие клиенты») для своих приложений или своих публичных SDK — мы не знаем ни одного заметного на рынке продукта, разработанного в этой парадигме (кроме, разве что, протоколов удалённых терминалов)
Тут очень важно понимать что такое "тонкий клиент" по Вашему а то таких технологий может оказаться очень много, например бутстрапер любой MMORPG это тонкий клиент или нет? А если мы говорим о вебе то нет ни одного заметного продукта потому что фаза эта закончилась провалом для таких технологий как Flash, Silverlight, Java Applet и других. Вместо этого усилия сообщества были направлены на то чтобы все что было в этих технологиях появилось и в web браузере и не надо было кучу тонких клиентов ставить заходя на рандомный сайт. Сейчас никто этим не занят потому что в этом просто нет никакого смысла. Уже даже десктопные приложения делают на технологиях вроде Electron которые по сути web браузер с щепоткой клиентского кода.
разработать серверный код управления UI ничуть не проще, нежели клиентский;
Возможно Вы имели ввиду "разрабатывать клиентское приложение работающее не на клиенте а по факту работающее на сервере сложнее"?
следует различать Backend-Driven UI и технологию серверного рендеринга (SSR). Второе подразумевает, что одно и то же состояние UI (как правило, в виде HTML-разметки или аналогичного декларативного описания) может быть сгенерировано как сервером, так и клиентом. В SSR, однако, подразумевается, что клиент может интерпретировать ответ сервера и извлекать из него семантические данные.
И чем плох вариант с генерация клиентом?
Когда соединение с сервером нестабильно или теряется Во что превратится UI? Одно дело UI "на клиенте" он просто покажет крутилку или что-то в таком духе но сам по себе продолжит быть отзывчивым, весь оффлайн функционал продолжит работу. Но в случае с Backend-Driven UI не получиться поставить даже крутилку потому что связь просто пропадет. Сетевые проблемы также могут сильно подпортить UX пользователю он будет либо часто видеть крутилку, либо нажимать на кнопки и другие интерактивные элементы а интеракции не будут происходить.
Можно но это сильно зависит от того сколько событий Вы собрались отправлять и их размер. Трафик от всех вкладок может быть большим и тогда один вебсокет будет не самой хорошей идеей особенно если его сеансы влияют на интерактивность UI. Т.е. я нажал на кнопку и ничего не произошло либо включилась крутилка и зависла.
Я имел ввиду когда два приложения могут делиться какими-то знаниями уникальными для друг друга. Т.е. есть два приложения - приложение с заказом карт и приложение с подарками. Допустим при заказе карты я получаю подарок и бизнес кейс что я перехожу с одного приложения на другое но при этом они вполне могут обменяться данными. Приложение подарков может получить информацию о карте (название например) и отобразить название карты и еще что-то плюс подарок. Простите если пример странный, пытался придумать что-то по Вашему профилю.
Шина да самый верный вариант, моя мысль была в том чтобы не изобретать велосипед беря какую-то библиотеку для шины а использовать DOM events в котором нет всех проблем которые я выше описал.
Если каждое приложение будет устанавливать веб-сокет то сервер очень легко может прилечь а если открыть пару тройку вкладок одного и того же сайта где такое решение реализовано то проблема увеличиться как n*k где n это количество вкладок а k это количество приложений внутри каждой вкладки.
"Более общим решением будет связать микрофронтенды через хост-приложение, например создав сервис, где мы опишем, какие МФ есть в приложении, и их API. Так сами микрофронтенды не будут знать о существовании друг друга, но хост-приложение должно уметь обрабатывать их запросы." мне кажется или это противоречит идее микрофронтендов? У Вас получается god-object "хост-приложение" которое обо всех все знает хотя по факту должно быть наоборот. "Хост-приложение" в теории вообще не должно ничего знать а просто загружать требуемые модули.
"В микрофронтенде мы используем метод отправки события и саму шину берем из хост-приложения через синглтон InjectionToken" начнем с того что браузер уже из коробки имеет реализацию событийно-ориентированного подхода. Также шина добавляет целый кластер новых проблем. Как понять что произошла ошибка в action-е и вообще он выполнился? Если не выполнился стоит ли попробовать повторить? Что если ошибка произошла в самой шине? Что если нужно не просто кейс по типу "кликнули на что-то и надо что-то выполнить" а сложнее по типу "дай мне информацию о то то о чем знаешь только ты"? Что если надо выполнять по цепочке несколько вызовов?
"Связанность в некотором смысле является платой за связность" - может быть все же поискать более разные слова для определения этих терминов потому что очень сильно сливаются в тексте.
Ваш подход хороший, т.е. кейс где Вы сделали на каждый "похожий но немного другой" отдельный компонент который внутри собирает нужный вид с нюансами. Проблемы у такого похода начинаются когда требуется совместить или использовать две и более модели которые вроде как обычно не связаны друг с другом но вот в каком-то одном месте они связаны и друг от друга зависят (внешний вид зависит). Мы можем объединить по этому же принципу в один компонент но он будет принимать уже не одну модель а n моделей что вполне может приводить к ситуации как Выше в статье мы вроде вынесли и собрали в одном месте но пропов (моделей) у него много для его настройки. Эту ситуацию можно допустим решить изменением структуры ответа у бекэнда на содержащую общую модель но не всегда это резонно и возможно, особенно если данные уже есть на стороне фронта смысла допустим получать их еще раз нет. Второе неудобство у данного подхода в том что если допустим я имею десять таких компонентов и что-то меняться фундаментально то в них во всех (или как минимум в большинство) придется зайти и что-то поменять. Я думаю что подход к разделению компонентов не может быть один, надо применять разные в зависимости от разных кейсов для применения компонентов. У нас в команде используется несколько разных подходов в том числе и все которые Вы описали в статье. Помимо них есть например еще подход когда компонент с бизнес логикой выноситься отдельно а компонент с представлением не содержит логики вообще. Вот пример кнопку мы разделили на два компонента один содержащий логику и состояние https://github.com/P-RCollaboration/ProvueCoreComponents/blob/main/src/states/ButtonState.vue и второй содержащий представление https://github.com/P-RCollaboration/ProvueCoreComponents/blob/main/src/views/material/MaterialButtonView.vue Суть такого подхода в том что можно без изменения компонента с бизнес логикой тасовать компоненты с его представлениями коих может быть много. Пример с кнопкой когда у нас логика нажатия и обработчик кнопки одинаковый у всех кнопок но выглядеть она может в разных частях системы по разному и для каждого представления будет свой компонент но без логики. Вот тут можно посмотреть пример как это склеить воедино https://github.com/P-RCollaboration/ProvueCoreComponents/blob/main/src/examples/helloworld/ButtonsDemo.vue Пример для кнопки но его можно натянуть и на бизнес логику.
В Steam-е моя карта visa была удалена, а на все остальные варианты написано сообщение "В данный момент покупка с помощью выбранного способа оплаты невозможна. Приносим извинения за доставленные неудобства."
Серьёзно? Как минимум у нас и в контексте WPF везде натыкаешься на одно и тоже.
Я работал на нескольких проектах и на них использовались Prism, MVVM Light, Caliburn.Micro, MvvmCross, ReactiveUI, Cinch в остальных были свои велосипеды. Тут еще стоит упомянуть что хоть все они и решали одну и ту же проблему но делали это со своими ньюансами. Т.е. просто пересесть с одной на другую поменяв названия методов не представляется возможным. Незнаю может это мне так повезло...
Проблема WPF/UWP технологий я думаю в том что нет развития XAML-а как декларативного языка. Система привязки и MVVM дак вообще не развивается. Из последних инноваций только x:Bind можно вспомнить и то это для очень узких кейсов. Нет сильной готовой библиотеки от Microsoft для этого. По сути они вообще не развивают это направление, в голом проекте тебе надо самому буквально с нуля делать реактивность. Из-за чего и получилось что какие-то конторы делают свои велосипеды, другие делают библиотеки количество которых слава богу не приближается к таковым в JavaScript но все равно очень большое и самое главное в них авторы по разному представляют как что должно работать. Т.е. например переходя с одной работы на другую вероятность там встретить похожую библиотеку или вообще какую-нибудь знакомую тебе опенсорсную крайне мала. А система привязок к сожалению очень сильно сдает, если хотя бы раз делать реактивность на JS с библиотеками вроде Vue.js/Angular/etc когда прямо в шаблоне можно просто написать property1 > property2 ? "value1" + property3 : "value2" то возвращаясь к конвертерам и простыне по типу "this.OneWayBind(ViewModel, vm => vm.Series, v => v.Plot.Series) .DisposeWith(disposable); " становится очень грустно. На маленьких и ближе к средним проектах это впринципе не особо заметно но когда проект большой все эти недостатки начинают сильно бить по скорости разработки и негативно сказывать на объеме кода. Мне кажется что развитием было бы либо замена XAML на что-то новое менее многословное либо как поступили в Asp.Net придумав Razor который позволяет писать Html с динамическими вставками, также круто было бы если бы можно было писать XAML с вклиниванием C# которым было бы легко генерить некоторые куски код.
Много бойлерплейт-кода: создать HTTP-клиент, HTTP client factory, договориться о сериализации (JSON, XML или другие варианты), учесть различные форматы дат, чисел и так далее, кейсинг. Соответственно, много возможностей для возникновения ошибок — нужно писать DTO-классы специально для транспорта.
gRPC тоже не является серебрянной пулей которая это целиком решает. Например использование nullable типов в C# может выстрелить когда какой-нибудь клиент захочет его использовать из языков где нет nullable типов. Незнаю как сейчас но раньше decimal не поддерживался что требовало создание своего типа который после передачи надо было склеивать в родной тип decimal на стороне внешнего клиента и в обратную сторону аналогично.
Я конечно не спец по биндингу для языка Python но сама технология Qt поддерживает дополнительный подход к разработке интерфейса в виде использования декларативного языка QML. На него хорошо ложится разделение логики и UI и возможно использование различных паттернов типа MVVM. Единственный недостаток который есть у этой технологии если нужен прям родной нативный UI из системы то она к сожалению такого не предоставляет.
Меня всегда интересовало зачем взяли такой тяжеловесный язык как C# в качестве скриптового языка для игрового движка, когда можно было взять что-то более простое вроде Lua или Python. С одной стороны понятно что можно использовать библиотеки из мира C# но вот читая такие статьи у меня складывается впечатление что разработчики библиотек могут и не знать о таких нюансах и вовсю использовать linq, foreach и прочие влияющие на производительность вещи. А с другой стороны если для него надо писать "свой" Linq и бороться за каждую сборку мусора то стоит ли игра свеч?
Это очень хорошая идея но ровно до того момента когда появится интерактивность внутри этого представления.
Решив проблему с универсальным UI на каждых чих приезжающий с сервера возникнет совсем другой класс проблем. Сетевых проблем, результатом которых будет либо недогруженный UI или несоответствие версий UI, измененные пути ведущие в 404 и т.п.
Тут очень важно понимать что такое "тонкий клиент" по Вашему а то таких технологий может оказаться очень много, например бутстрапер любой MMORPG это тонкий клиент или нет?
А если мы говорим о вебе то нет ни одного заметного продукта потому что фаза эта закончилась провалом для таких технологий как Flash, Silverlight, Java Applet и других.
Вместо этого усилия сообщества были направлены на то чтобы все что было в этих технологиях появилось и в web браузере и не надо было кучу тонких клиентов ставить заходя на рандомный сайт. Сейчас никто этим не занят потому что в этом просто нет никакого смысла. Уже даже десктопные приложения делают на технологиях вроде Electron которые по сути web браузер с щепоткой клиентского кода.
Возможно Вы имели ввиду "разрабатывать клиентское приложение работающее не на клиенте а по факту работающее на сервере сложнее"?
И чем плох вариант с генерация клиентом?
Когда соединение с сервером нестабильно или теряется Во что превратится UI? Одно дело UI "на клиенте" он просто покажет крутилку или что-то в таком духе но сам по себе продолжит быть отзывчивым, весь оффлайн функционал продолжит работу. Но в случае с Backend-Driven UI не получиться поставить даже крутилку потому что связь просто пропадет. Сетевые проблемы также могут сильно подпортить UX пользователю он будет либо часто видеть крутилку, либо нажимать на кнопки и другие интерактивные элементы а интеракции не будут происходить.
Можно но это сильно зависит от того сколько событий Вы собрались отправлять и их размер. Трафик от всех вкладок может быть большим и тогда один вебсокет будет не самой хорошей идеей особенно если его сеансы влияют на интерактивность UI. Т.е. я нажал на кнопку и ничего не произошло либо включилась крутилка и зависла.
Я имел ввиду когда два приложения могут делиться какими-то знаниями уникальными для друг друга. Т.е. есть два приложения - приложение с заказом карт и приложение с подарками. Допустим при заказе карты я получаю подарок и бизнес кейс что я перехожу с одного приложения на другое но при этом они вполне могут обменяться данными. Приложение подарков может получить информацию о карте (название например) и отобразить название карты и еще что-то плюс подарок. Простите если пример странный, пытался придумать что-то по Вашему профилю.
Шина да самый верный вариант, моя мысль была в том чтобы не изобретать велосипед беря какую-то библиотеку для шины а использовать DOM events в котором нет всех проблем которые я выше описал.
Если каждое приложение будет устанавливать веб-сокет то сервер очень легко может прилечь а если открыть пару тройку вкладок одного и того же сайта где такое решение реализовано то проблема увеличиться как n*k где n это количество вкладок а k это количество приложений внутри каждой вкладки.
"Более общим решением будет связать микрофронтенды через хост-приложение, например создав сервис, где мы опишем, какие МФ есть в приложении, и их API. Так сами микрофронтенды не будут знать о существовании друг друга, но хост-приложение должно уметь обрабатывать их запросы." мне кажется или это противоречит идее микрофронтендов? У Вас получается god-object "хост-приложение" которое обо всех все знает хотя по факту должно быть наоборот. "Хост-приложение" в теории вообще не должно ничего знать а просто загружать требуемые модули.
"В микрофронтенде мы используем метод отправки события и саму шину берем из хост-приложения через синглтон InjectionToken" начнем с того что браузер уже из коробки имеет реализацию событийно-ориентированного подхода. Также шина добавляет целый кластер новых проблем. Как понять что произошла ошибка в action-е и вообще он выполнился? Если не выполнился стоит ли попробовать повторить? Что если ошибка произошла в самой шине? Что если нужно не просто кейс по типу "кликнули на что-то и надо что-то выполнить" а сложнее по типу "дай мне информацию о то то о чем знаешь только ты"? Что если надо выполнять по цепочке несколько вызовов?
"Связанность в некотором смысле является платой за связность" - может быть все же поискать более разные слова для определения этих терминов потому что очень сильно сливаются в тексте.
Ваш подход хороший, т.е. кейс где Вы сделали на каждый "похожий но немного другой" отдельный компонент который внутри собирает нужный вид с нюансами. Проблемы у такого похода начинаются когда требуется совместить или использовать две и более модели которые вроде как обычно не связаны друг с другом но вот в каком-то одном месте они связаны и друг от друга зависят (внешний вид зависит). Мы можем объединить по этому же принципу в один компонент но он будет принимать уже не одну модель а n моделей что вполне может приводить к ситуации как Выше в статье мы вроде вынесли и собрали в одном месте но пропов (моделей) у него много для его настройки. Эту ситуацию можно допустим решить изменением структуры ответа у бекэнда на содержащую общую модель но не всегда это резонно и возможно, особенно если данные уже есть на стороне фронта смысла допустим получать их еще раз нет. Второе неудобство у данного подхода в том что если допустим я имею десять таких компонентов и что-то меняться фундаментально то в них во всех (или как минимум в большинство) придется зайти и что-то поменять. Я думаю что подход к разделению компонентов не может быть один, надо применять разные в зависимости от разных кейсов для применения компонентов. У нас в команде используется несколько разных подходов в том числе и все которые Вы описали в статье. Помимо них есть например еще подход когда компонент с бизнес логикой выноситься отдельно а компонент с представлением не содержит логики вообще. Вот пример кнопку мы разделили на два компонента один содержащий логику и состояние https://github.com/P-RCollaboration/ProvueCoreComponents/blob/main/src/states/ButtonState.vue и второй содержащий представление https://github.com/P-RCollaboration/ProvueCoreComponents/blob/main/src/views/material/MaterialButtonView.vue Суть такого подхода в том что можно без изменения компонента с бизнес логикой тасовать компоненты с его представлениями коих может быть много. Пример с кнопкой когда у нас логика нажатия и обработчик кнопки одинаковый у всех кнопок но выглядеть она может в разных частях системы по разному и для каждого представления будет свой компонент но без логики. Вот тут можно посмотреть пример как это склеить воедино https://github.com/P-RCollaboration/ProvueCoreComponents/blob/main/src/examples/helloworld/ButtonsDemo.vue Пример для кнопки но его можно натянуть и на бизнес логику.
Можете пояснить что это значит? Как подход отпочковался от шаблона и в чем этот подход заключается?
В Steam-е моя карта visa была удалена, а на все остальные варианты написано сообщение "В данный момент покупка с помощью выбранного способа оплаты невозможна. Приносим извинения за доставленные неудобства."
Я работал на нескольких проектах и на них использовались Prism, MVVM Light, Caliburn.Micro, MvvmCross, ReactiveUI, Cinch в остальных были свои велосипеды. Тут еще стоит упомянуть что хоть все они и решали одну и ту же проблему но делали это со своими ньюансами. Т.е. просто пересесть с одной на другую поменяв названия методов не представляется возможным. Незнаю может это мне так повезло...
Проблема WPF/UWP технологий я думаю в том что нет развития XAML-а как декларативного языка. Система привязки и MVVM дак вообще не развивается. Из последних инноваций только x:Bind можно вспомнить и то это для очень узких кейсов. Нет сильной готовой библиотеки от Microsoft для этого. По сути они вообще не развивают это направление, в голом проекте тебе надо самому буквально с нуля делать реактивность. Из-за чего и получилось что какие-то конторы делают свои велосипеды, другие делают библиотеки количество которых слава богу не приближается к таковым в JavaScript но все равно очень большое и самое главное в них авторы по разному представляют как что должно работать. Т.е. например переходя с одной работы на другую вероятность там встретить похожую библиотеку или вообще какую-нибудь знакомую тебе опенсорсную крайне мала. А система привязок к сожалению очень сильно сдает, если хотя бы раз делать реактивность на JS с библиотеками вроде Vue.js/Angular/etc когда прямо в шаблоне можно просто написать property1 > property2 ? "value1" + property3 : "value2" то возвращаясь к конвертерам и простыне по типу "this.OneWayBind(ViewModel, vm => vm.Series, v => v.Plot.Series) .DisposeWith(disposable); " становится очень грустно. На маленьких и ближе к средним проектах это впринципе не особо заметно но когда проект большой все эти недостатки начинают сильно бить по скорости разработки и негативно сказывать на объеме кода. Мне кажется что развитием было бы либо замена XAML на что-то новое менее многословное либо как поступили в Asp.Net придумав Razor который позволяет писать Html с динамическими вставками, также круто было бы если бы можно было писать XAML с вклиниванием C# которым было бы легко генерить некоторые куски код.
gRPC тоже не является серебрянной пулей которая это целиком решает. Например использование nullable типов в C# может выстрелить когда какой-нибудь клиент захочет его использовать из языков где нет nullable типов. Незнаю как сейчас но раньше decimal не поддерживался что требовало создание своего типа который после передачи надо было склеивать в родной тип decimal на стороне внешнего клиента и в обратную сторону аналогично.
Я конечно не спец по биндингу для языка Python но сама технология Qt поддерживает дополнительный подход к разработке интерфейса в виде использования декларативного языка QML. На него хорошо ложится разделение логики и UI и возможно использование различных паттернов типа MVVM. Единственный недостаток который есть у этой технологии если нужен прям родной нативный UI из системы то она к сожалению такого не предоставляет.
Меня всегда интересовало зачем взяли такой тяжеловесный язык как C# в качестве скриптового языка для игрового движка, когда можно было взять что-то более простое вроде Lua или Python. С одной стороны понятно что можно использовать библиотеки из мира C# но вот читая такие статьи у меня складывается впечатление что разработчики библиотек могут и не знать о таких нюансах и вовсю использовать linq, foreach и прочие влияющие на производительность вещи. А с другой стороны если для него надо писать "свой" Linq и бороться за каждую сборку мусора то стоит ли игра свеч?