Эта цитата действительно заставила меня усмехнуться. Тем не менее, я считаю, что минимизация побочных эффектов действительно переводится в код, который намного проще продумывать и поддерживать. Однако у меня нет возможности изучать функциональное программирование так, как мне хотелось бы.
Когда я работаю с объектно-ориентированными и процедурными языками, которые вращаются вокруг побочных эффектов, я смотрю на это, чтобы содержать и изолировать побочные эффекты.
В качестве базового примера, видеоигра имеет побочный эффект визуализации графики на экране. Однако в отношении побочных эффектов здесь есть два разных пути проектирования.
Один пытается свести к минимуму и ослабить взаимосвязь, сделав средство визуализации очень абстрактным и в основном указав, что визуализировать. Затем другие части системы сообщают рендереру, что рисовать, и это может быть набор примитивов, таких как треугольники и точки с матрицами проекции и вида модели, или, может быть, что-то более высокоуровневое, например абстрактные модели, камеры, источники света и частицы. В любом случае, такой дизайн вращается вокруг многих вещей, вызывающих внешние побочные эффекты, поскольку потенциально многие части кодовой базы будут подталкивать изменения к рендереру (независимо от того, насколько абстрактным или косвенным, чистый эффект по-прежнему представляет собой целую кучу вещей в таком система, запускающая побочные эффекты внешнего рендеринга).
Другой способ - сдерживать / изолировать эти побочные эффекты. Вместо того, чтобы сообщать рендереру, что нужно рендерить, он становится связанным с игровым миром (хотя это могут быть просто некоторые базовые абстракции и, возможно, доступ к графу сцены). Теперь он получает доступ к сцене самостоятельно (доступ только для чтения), просматривает сцену и решает, что визуализировать, используя дизайн в стиле вытягивания. Это приводит к большей связи от рендерера с игровым миром, но это также означает, что побочные эффекты, связанные с выводом на экран, теперь полностью содержатся внутри рендерера.
Этот последний дизайн содержит или изолирует побочные эффекты, и я считаю, что такой дизайн намного проще поддерживать и поддерживать правильным. Это по-прежнему вызывает побочные эффекты, но все побочные эффекты, связанные с выводом графики на экран, теперь полностью содержатся в средстве визуализации. Если там есть проблема, вы знаете, что ошибка будет в коде рендерера, а не в результате чего-то внешнего неправильного использования и указания ему неправильных действий.
Из-за этого, когда дело доходит до связи, я всегда считал более желательным максимизировать эфферентные (исходящие) связи в вещах, которые вызывают внешние побочные эффекты, и минимизировать афферентные (входящие) связи. Это применимо независимо от абстракций. В контексте побочных эффектов зависимость от IRenderer
по-прежнему является зависимостью от конкретного Renderer
в том, что касается коммуникации в отношении того, какие побочные эффекты могут произойти. Абстракция не имеет значения, какие побочные эффекты могут возникнуть.
Средство визуализации должно зависеть от остального мира, чтобы полностью изолировать эти побочные эффекты от экрана; остальной мир не должен зависеть от рендерера. Такая же аналогия с файловой заставкой. Хранитель файла не должен сообщать, что нужно сохранить, от внешнего мира. Он должен посмотреть на окружающий мир и самостоятельно решить, на чем сэкономить. Таков был бы путь проектирования, который стремится изолировать и сдерживать побочные эффекты; он, как правило, больше основан на вытягивании, чем на выталкивании. Результат имеет тенденцию вводить немного больше связи (хотя она может быть слабой), если вы графически отображаете зависимости, поскольку заставка, возможно, потребуется связать с вещами, которые она даже не заинтересована в сохранении, или рендереру может потребоваться доступ только для чтения к вещам. он даже не заинтересован в рендеринге, чтобы обнаружить то, что ему интересно в рендеринге.
Однако конечным результатом является то, что зависимости текут прочь от побочных эффектов, а не в сторону побочных эффектов. Когда у нас есть система со многими зависимостями, направленными на выталкивание внешних побочных эффектов, я всегда считал, что их труднее всего рассуждать, поскольку многие части системы потенциально могут изменять внешние состояния до такой степени, что не просто сложно понять, что произойдет, но также когда и где. Итак, самый простой способ исправить / предотвратить эту проблему - попытаться заставить зависимости течь прочь от побочных эффектов, а не навстречу им.
В любом случае, я предпочел эти типы проектов практическим способом избежать ошибок, а также помочь обнаружить и изолировать их, когда они существуют, чтобы облегчить их воспроизведение и исправление.
Еще одна полезная стратегия, которую я нахожу, - сделать побочные эффекты более однородными для любого заданного цикла / фазы системы. Например, вместо того, чтобы выполнять цикл, который удаляет связанные данные с чего-либо, разъединяет их, а затем удаляет, я обнаружил, что намного проще, если вы сделаете три однородных цикла в таких случаях. Первый однородный цикл может удалить связанные данные. Второй однородный цикл может разъединить узел. Третий однородный цикл может удалить его из остальной системы. Это примечание более низкого уровня, связанное больше с реализацией, чем с дизайном, но я часто обнаруживал, что результат легче обдумывать, поддерживать и даже оптимизировать (проще распараллеливать, например, и с улучшенной локальностью ссылок) - вы берете эти неоднородные петли вызывают несколько различных типов побочных эффектов и разбивают их на несколько однородных петель, каждая из которых запускает только один единый вид побочных эффектов.
person
Community
schedule
03.01.2018