একটি খাঁটি ফাংশন হ'ল:
- হবে সবসময় একই আর্গুমেন্ট দেওয়া একই ফলাফল দিতে
- কোন পর্যবেক্ষণযোগ্য পার্শ্ব প্রতিক্রিয়া নেই (যেমন রাষ্ট্র পরিবর্তন)
ধরুন আমরা ব্যবহারকারীর লগইন পরিচালনা করতে কিছু কোড লিখছি, যেখানে আমরা সরবরাহ করা ব্যবহারকারীর নাম এবং পাসওয়ার্ড সঠিক কিনা তা পরীক্ষা করে দেখতে চাই এবং অনেক ব্যর্থ প্রচেষ্টা থাকলে ব্যবহারকারী লগ ইন করতে বাধা দেয়। একটি অপরিহার্য শৈলীতে আমাদের কোডটি দেখতে এরকম হতে পারে:
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
এখন একটি খাঁটি ফাংশন এবং ফলস্বরূপ মূল ব্যবহারকারীর প্রমাণীকরণের যুক্তি কোনও বাহ্যিক নির্ভরতার উপহাস না করে ইউনিট পরীক্ষা করা যেতে পারে। এটি কারণ হ'ল ডেটাবেসটির সাথে মিথস্ক্রিয়াটি কল স্ট্যাককে উচ্চতরভাবে পরিচালনা করা হয়।