Информация об изменениях

Сообщение Re: Связывание форм (GUI) с данными: императивно vs декларат от 17.10.2020 3:42

Изменено 17.10.2020 4:01 VladD2

Re: Связывание форм (GUI) с данными: императивно vs декларативно
Здравствуйте, Shmj, Вы писали:

S>Почему все верят, что декларативный подход рулит и на порядок упрощает работу?


Потому что это решает не одну задачу, а множество. И чем больше задач ты решаешь, тем лучше декларативный подход.

S>Вот, давайте на примере.


Тут проблемы две.
1. В ВПФ декларативность убогая. Сам язык разметки — убогий. Программирование на ХМЛ, плюс динамическая типизация, плюс кране скудная и не удобная расширяемость. Вот если взять хотя бы АММИ, то расклад меняется.
2. Ты решаешь только одну задачу — отображение данных. И сравниваешь только объем кода. А в реальности задач бывает куда больше.

Вот смотри. У нас ГУЙ решает следующие задачи:
1. Переиспользование воью-моеделей.
2. Локализация.
3. Тестирование. Тестируется сам продукт, но через дерганье вью-моделей.
4. Отделение верстки от кода логики. Программист только рисует набросок формы и реализует ВМки с биндингом, а уже за реальное визуальное представление отвечают проффесионалы в верстке. Перередически производится рескининг (смена внешниего вида).
5. Реактивность и гибкость ГУя.
6. Автоматически снять скриншоты для всех переводов и для всех состояний, чтобы переводчики могли проверить правильность переводов и не были вынуждены протыкивать весь продукт годами (форм море).

S>Есть поле на форме, вам нужно установить дату и подсветить, если дата нечетная.


S>Императивный подход (примерно):


S>
S>DateTextBox.Text = UIConverter.ConvertToText(businessObject.Date);

S>if (businessObject.Date.IsOdd)
S>   DateTextBox.Background = Color.Red;
S>


И вот теперь нам нужно поменять цвет. Нам придется править код.
Далее нам нужно оттестировать все это. А присвоения хер знает где. Мы не можем тупо присвоить дату в ВМке и быть уверенным, что гуй ее отобразит как надо.
Следующая задача — локализация. Мы должны опять таки править код.
И так далее.

S>Декларативный подход типа:


S>
S><Window.Resources>
S>        <local:DateBacklightConverter x:Key="dateBacklightConverter" />
S></Window.Resources>

S><TextBox Text="{Binding Date}" Background="{Binding Source=Date,Converter={StaticResource dateBacklightConverter}}" />
S>


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

Но согласен, что читабельность у этого птичьего языка не высока.

Правильно это бы выглядело как-то так:
using dateBacklightConverter=X.Y.X.dateBacklightConverter;
...
TextBox { Text=Date; Style=dateBacklightConverter(Date); }

Или даже:
using dateBacklightConverter=X.Y.X.dateBacklightConverter;
...
TextBox { Text=Date; Style=Date.IsOdd ? Normal : Highlighted; }


То есть это вопрос грамотной реализации языка попсания вьюх.

S>Теперь давайте какие реальные плюсы у т.н. декларативного? Букв меньше не стало.


У меня стало.

S>Совокупная сложность кода не понизилась


1. Код раделен на представление и ВМку. Теперь его можно тестировать.
2. Его внешний вид определяется стилями не связанными с кодом. Стало быть их можно легко менять.
3. Наш код реактивен, а значит его легче тестировать.
4. Мы можем переиспользовать ВМки в других вьюшках.

S> — все равно в конвертере есть проверка if и выбор цвета.


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

S>В XML-е писать не удобнее, но даже не в этом суть.


Полностью согласен. ХМЛ — плохой язык для программирования, а вьюхи все равно являются кодом, хоть и декларативным.

Еще минус — динамическая природа ВПФ. Но кое-ка ее обуздывает Решарпер и Райдер (в студии поддержка — говно).

S>Получается, что никакого реального преимущества, кроме хайпа, нет


Ты ее не там ищешь.

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

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

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

В общем, сама идея раздения на представления и модели-представлений — здравая. ХМЛ — идиотизм! Динамка — астдай! То что ВМки нужно руками выписывать (все эти
INotifyPropertyChanged — тоже оверхэд).

Идеальное решение мне видится следующим образом:
1. Все вьюхи должны иметь статически заданный тип ВМки (контролируется ИДЕ и компилятором). При этом допускается сабтайпинг на интерфейсах.
2. Вьюхи должны поддерживать паттерн матчинг по типам сабатйпинга.
3. Во вьюхах должен использоваться специально разработанный для этого язык без всяких ХМЛ-ей или джейсонов.
4. Во вьюхах должны поддерживаться гибкие операторы как в нормальных императивных языках.
5. Для описания ВМок язык должен поддерживать зависимые вычисления (как ленивость в Хаскеле). Это позволит обойтись без костылей в виде
INotifyPropertyChanged. Просто пишешь:
view model MyVM
{
  dependent string   PropX = PropY + 42 + PropZ;
  dependent string   PropY = DoSome(PropA, PropB);
  dependent int      PropA;
  dependent DateTime PropB;
  ...
  void Init()
  {
    PropA = ReadFromDb(...);
  }

  string DoSome(int x, DateTime y) { какие-то вычисления }
}

view MyView
{
   TextBox   { Text=PropB; Style=A; }
   TextBlock { Text=PropA; Style=B; }
   TextBlock { Text=PropZ; Style=B; }
}

И все вычисления распространяются автоматически. При этом все статически проверяется при компиляции и в ИДЕ.
Re: Связывание форм (GUI) с данными: императивно vs декларат
Здравствуйте, Shmj, Вы писали:

S>Почему все верят, что декларативный подход рулит и на порядок упрощает работу?


Потому что это решает не одну задачу, а множество. И чем больше задач ты решаешь, тем лучше декларативный подход.

S>Вот, давайте на примере.


Тут проблемы две.
1. В ВПФ декларативность убогая. Сам язык разметки — убогий. Программирование на ХМЛ, плюс динамическая типизация, плюс кране скудная и не удобная расширяемость. Вот если взять хотя бы АММИ, то расклад меняется.
2. Ты решаешь только одну задачу — отображение данных. И сравниваешь только объем кода. А в реальности задач бывает куда больше.

Вот смотри. У нас ГУЙ решает следующие задачи:
1. Переиспользование воью-моеделей.
2. Локализация.
3. Тестирование. Тестируется сам продукт, но через дерганье вью-моделей.
4. Отделение верстки от кода логики. Программист только рисует набросок формы и реализует ВМки с биндингом, а уже за реальное визуальное представление отвечают проффесионалы в верстке. Перередически производится рескининг (смена внешниего вида).
5. Реактивность и гибкость ГУя.
6. Автоматически снять скриншоты для всех переводов и для всех состояний, чтобы переводчики могли проверить правильность переводов и не были вынуждены протыкивать весь продукт годами (форм море).

S>Есть поле на форме, вам нужно установить дату и подсветить, если дата нечетная.


S>Императивный подход (примерно):


S>
S>DateTextBox.Text = UIConverter.ConvertToText(businessObject.Date);

S>if (businessObject.Date.IsOdd)
S>   DateTextBox.Background = Color.Red;
S>


И вот теперь нам нужно поменять цвет. Нам придется править код.
Далее нам нужно оттестировать все это. А присвоения хер знает где. Мы не можем тупо присвоить дату в ВМке и быть уверенным, что гуй ее отобразит как надо.
Следующая задача — локализация. Мы должны опять таки править код.
И так далее.

S>Декларативный подход типа:


S>
S><Window.Resources>
S>        <local:DateBacklightConverter x:Key="dateBacklightConverter" />
S></Window.Resources>

S><TextBox Text="{Binding Date}" Background="{Binding Source=Date,Converter={StaticResource dateBacklightConverter}}" />
S>


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

Но согласен, что читабельность у этого птичьего языка не высока.

Правильно это бы выглядело как-то так:
using dateBacklightConverter=X.Y.X.dateBacklightConverter;
...
TextBox { Text=Date; Style=dateBacklightConverter(Date); }

Или даже:
using dateBacklightConverter=X.Y.X.dateBacklightConverter;
...
TextBox { Text=Date; Style=Date.IsOdd ? Normal : Highlighted; }


То есть это вопрос грамотной реализации языка попсания вьюх.

S>Теперь давайте какие реальные плюсы у т.н. декларативного? Букв меньше не стало.


У меня стало.

S>Совокупная сложность кода не понизилась


1. Код раделен на представление и ВМку. Теперь его можно тестировать.
2. Его внешний вид определяется стилями не связанными с кодом. Стало быть их можно легко менять.
3. Наш код реактивен, а значит его легче тестировать.
4. Мы можем переиспользовать ВМки в других вьюшках.

S> — все равно в конвертере есть проверка if и выбор цвета.


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

S>В XML-е писать не удобнее, но даже не в этом суть.


Полностью согласен. ХМЛ — плохой язык для программирования, а вьюхи все равно являются кодом, хоть и декларативным.

Еще минус — динамическая природа ВПФ. Но кое-ка ее обуздывает Решарпер и Райдер (в студии поддержка — говно).

S>Получается, что никакого реального преимущества, кроме хайпа, нет


Ты ее не там ищешь.

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

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

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

В общем, сама идея раздения на представления и модели-представлений — здравая. ХМЛ — идиотизм! Динамка — астдай! То что ВМки нужно руками выписывать (все эти
INotifyPropertyChanged — тоже оверхэд).

Идеальное решение мне видится следующим образом:
1. Все вьюхи должны иметь статически заданный тип ВМки (контролируется ИДЕ и компилятором). При этом допускается сабтайпинг на интерфейсах.
2. Вьюхи должны поддерживать паттерн матчинг по типам сабатйпинга.
3. Во вьюхах должен использоваться специально разработанный для этого язык без всяких ХМЛ-ей или джейсонов.
4. Во вьюхах должны поддерживаться гибкие операторы как в нормальных императивных языках.
5. Для описания ВМок язык должен поддерживать зависимые вычисления (как ленивость в Хаскеле). Это позволит обойтись без костылей в виде
INotifyPropertyChanged. Просто пишешь:
view model MyVM
{
  dependent string   PropX = PropY + 42 + PropZ;
  dependent string   PropY = DoSome(PropA, PropB);
  dependent int      PropA;
  dependent DateTime PropB;
  ...
  void Init()
  {
    PropA = ReadFromDb(...);
  }

  string DoSome(int x, DateTime y) { какие-то вычисления }
}

view MyView
{
   TextBox   { Text=PropB; Style=A; }
   TextBlock { Text=PropA; Style=B; }
   TextBlock { Text=PropZ; Style=B; }
}

И все вычисления распространяются автоматически. При этом все статически проверяется при компиляции и в ИДЕ.

Ну, а стили должны быть как в CSS, а не как в ВПФ в виде наборов присвоений свойств, триггеров и шаблонов верстки (бррр!).