Чистий функція є той , який:
- Буду завжди дають той же результат , враховуючи ті ж аргументи
- Не має помітних побічних ефектів (наприклад, зміни стану)
Припустимо, ми пишемо якийсь код для обробки входу користувачів, де ми хочемо перевірити правильність наданих імені користувача та пароля та запобігти входу користувача, якщо занадто багато невдалих спроб. В імперативному стилі наш код може виглядати так:
bool UserLogin(string username, string password)
{
var user = _database.FindUser(username);
if (user == null)
{
return false;
}
if (user.FailedAttempts > 3)
{
return false;
}
// Password hashing omitted for brevity
if (user.Password != password)
{
_database.RecordFailedLoginAttempt(username);
}
return true;
}
Цілком зрозуміло, що це не чиста функція:
- Ця функція не завжди дає той же результат для заданого
username
і password
комбінації , як результат також залежить від записи користувача , що зберігається в базі даних.
- Функція може змінювати стан бази даних, тобто вона має побічні ефекти.
Також зауважте, що для тестування цієї функції нам потрібно знущатися над двома дзвінками до бази даних FindUser
та RecordFailedLoginAttempt
.
Якби ми переробили цей код у більш функціональний стиль, ми могли б закінчитися чимось таким:
bool UserLogin(string username, string password)
{
var user = _database.FindUser(username);
var result = UserLoginPure(user, password);
if (result == Result.FailedAttempt)
{
_database.RecordFailedLoginAttempt(username);
}
return result == Result.Success;
}
Result UserLoginPure(User user, string pasword)
{
if (user == null)
{
return Result.UserNotFound;
}
if (user.FailedAttempts > 3)
{
return Result.LoginAttemptsExceeded;
}
if (user.Password != password)
{
return Result.FailedAttempt;
}
return Result.Success;
}
Зауважте, що хоча UserLogin
функція все ще не є чистою, UserLoginPure
тепер функція є чистою функцією, і в результаті основна логіка автентифікації користувача може бути перевірена одиницею без необхідності висміювати будь-які зовнішні залежності. Це пояснюється тим, що взаємодія з базою даних обробляється вище до стека викликів.