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

Мои первые программы на BASIC

Когда я был еще ребенком, я создал свои первые представления, просто распечатав:

10 PRINT "Good morning Dave"

После печати пришел ввод. Ввод — это операция по изменению состояния программы:

10 PRINT "Hi"
20 INPUT "What is your name? ", N$
30 PRINT "Good morning"; N$
40 GOTO 20

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

SUB MainMenu()
  DO
    CALL PrintMainMenu
    INPUT “What option you choose? “, Option%
    CALL ExecuteMainOption(Option%)
  LOOP UNTIL Option% = 0
END SUB

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

Вход в объектно-ориентированный мир

Возможно, я мог бы обвинить в этом Java, но это не так. Первым языком программирования, который я использовал, был C++, за которым последовал VisualBasic (точнее, 2.0).

Объектно-ориентированное программирование было самой крутой вещью. Я помню переход от простых процедурных приложений к объектно-ориентированным. Объекты модели, которые заботятся о себе сами. Я помню, как написал один небольшой трассировщик лучей на C++, великолепно. Механизм рендеринга, который принимал в качестве входных данных абстрактные объекты, заставлял их пересекаться с лучами и генерировал впечатляющие изображения. Использование объектно-ориентированного программирования в моделях было замечательным.

Проблемы появились, когда я начал писать интерфейсы в объектно-ориентированном программировании.

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

В те дни я не понимал, что произошло. Сначала я подумал, что не понял MVC. Позже я подумал, что мне нужна лучшая методология. Я чувствовал, что что-то не так, но не знал, что. Я начал искать удобный способ кодирования. Я перепробовал много узоров. Почему-то все решения всегда казались чем-то вроде специальных решений.

Дублированные состояния, корень всех зол

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

Основной принцип объектно-ориентированного программирования заключается в том, что каждый объект сохраняет свое собственное состояние. Единственный способ взаимодействия с этим состоянием — через методы. Использование одного состояния объекта из другого объекта считается антипаттерном. Другими словами: объектно-ориентированное программирование поощряет дублирование состояний.

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

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

Функции не имеют состояния

В средах Front End для меня оказалось что-то удивительное: React. В начале я думал, что это на один фреймворк больше, но ошибся.

React рассматривает представление как нечто, что вы можете распечатать. Простой компонент React — это функция рендеринга. Идея создания компонентов в React состоит в том, чтобы позволить React лениво вызывать функции рендеринга; как чисто функциональный язык программирования.

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

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

Представление — это функция

Представления не должны сохранять состояние. Это дублирует состояние, а дублирование состояния приводит к повреждению данных и накладным расходам на синхронизацию.

Функции не имеют состояния, предсказуемы и многократно используются. ¿Почему бы просто не напечатать состояние, чтобы показать свое мнение?

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