I passed a technical test the other day, one part included a cheap string validation and I am wondering this can be further improved to be more versatile to requirement changes.
The requirements were something like that
Create a
Validate
method, which accepts a string and returnstrue
if it's valid andfalse
if it's not.A string is valid if it satisfies the rules below:
- The string must be at least 6 characters long and not exceed 16 characters.
- The string must contain only letters, numbers and optionally one hyphen (-).
- The string must start with a letter, and must not end with a hyphen. For example,
validate("Michelle Belle");
would return false because it contains a space.
My solution was like that:
public static class ComparableExtensions
{
public static bool IsStrictlyLowerThan<TComparable>(this TComparable comparable, TComparable value)
where TComparable : IComparable<TComparable>
{
return comparable.CompareTo(value) < 0;
}
public static bool IsStrictlyGreaterThan<TComparable>(this TComparable comparable, TComparable value)
where TComparable : IComparable<TComparable>
{
return comparable.CompareTo(value) > 0;
}
public static bool IsStrictlyNotBetween<TComparable>(this TComparable comparable, TComparable lowerBound, TComparable upperBound)
where TComparable : IComparable<TComparable>
{
if (lowerBound.IsStrictlyGreaterThan(upperBound))
{
throw new ArgumentOutOfRangeException(nameof(lowerBound) + nameof(upperBound));
}
return comparable.IsStrictlyLowerThan(lowerBound) || comparable.IsStrictlyGreaterThan(upperBound);
}
}
public static class CharExtensions
{
public static bool IsLetterOrDigit(this char c)
{
return char.IsLetterOrDigit(c);
}
public static bool IsLetter(this char c)
{
return char.IsLetter(c);
}
public static bool IsHyphen(this char c)
{
return c == '-';
}
}
public class Test
{
public static bool Validate(string str)
{
if (str.Length.IsStrictlyNotBetween(6, 16))
{
return false;
}
if (!str.First().IsLetter() || str.Last().IsHyphen())
{
return false;
}
var hyphenCount = 0;
for (var i = 1; i < str.Length - 1; i++)
{
if (str[i].IsLetterOrDigit())
{
continue;
}
if (str[i].IsHyphen())
{
hyphenCount++;
if (hyphenCount > 1)
{
return false;
}
}
else
{
return false;
}
}
return true;
}
}
I purposefully decided to not go with Regular Expressions to keep the logic readable and I am wondering if my code can be further refactored to incorporate new business rules.
IsHyphen
?IsStrictlyGreaterThan
? Why? Just write== '-'
in the code itself. \$\endgroup\$