Преимущество состоит в том, что чистые функции облегчают анализ вашего кода. Или, другими словами, побочные эффекты увеличивают сложность вашего кода.
Возьмите пример computeProductPrice
метода.
Чистый метод будет запрашивать количество продукта, валюту и т. Д. Вы знаете, что всякий раз, когда метод вызывается с одинаковыми аргументами, он всегда будет давать один и тот же результат.
- Вы даже можете кэшировать его и использовать кешированную версию.
- Вы можете сделать его ленивым и отложить его вызов, когда он вам действительно понадобится, зная, что значение тем временем не изменится.
- Вы можете вызывать метод несколько раз, зная, что у него не будет побочных эффектов.
- Вы можете рассуждать о самом методе в отрыве от мира, зная, что все, что ему нужно, это аргументы.
Не чистый метод будет более сложным в использовании и отладке. Поскольку это зависит от состояния переменных, отличных от аргументов и, возможно, их изменения, это означает, что он может давать разные результаты при многократном вызове или не иметь одинакового поведения, когда не вызывается вообще или вызывается слишком рано или слишком поздно.
пример
Представьте, что в структуре есть метод, который анализирует число:
decimal math.parse(string t)
У него нет ссылочной прозрачности, потому что это зависит от:
Переменная окружения, которая определяет систему нумерации, то есть Base 10 или что-то еще.
Переменная в math
библиотеке, которая определяет точность чисел для анализа. Таким образом, при значении 1
, синтаксический анализ строки "12.3456"
даст 12.3
.
Культура, которая определяет ожидаемое форматирование. Например, с fr-FR
, разбор "12.345"
даст 12345
, потому что символ разделения должен быть ,
, а не.
Представьте, как легко или сложно было бы работать с таким методом. С одним и тем же вводом вы можете получить радикально разные результаты в зависимости от момента, когда вы вызываете метод, потому что что-то где-то изменило переменную среды или переключило культуру или установило другую точность. Недетерминированный характер метода приведет к большему количеству ошибок и большему количеству отладочного кошмара. Вызов math.parse("12345")
и получение 5349
в качестве ответа, так как какой-то параллельный код анализировал восьмеричные числа, нехорошо.
Как исправить этот явно неработающий метод? Путем введения ссылочной прозрачности. Другими словами, избавившись от глобального состояния и переместив все на параметры метода:
decimal math.parse(string t, base=10, precision=20, culture=cultures.en_us)
Теперь, когда метод чистый, вы знаете, что независимо от того, когда вы вызываете метод, он всегда будет давать один и тот же результат для одних и тех же аргументов.