C# Switch Statement refactoring
The purpose of the code below is to determine if a particular date qualifies as a "weekend" i.e after 12:00 PM on Thursday, minimum 2 开发者_如何学Godays and before Monday 12:00 PM
Is there a better way? If-Else turns ugly and the Strategy pattern is way too much work for this.
public bool ValidateWeekend(DateTime pickupDate, DateTime dropoffDate)
{
TimeSpan ts = dropoffDate.Subtract(pickupDate);
if (ts.TotalDays >= 2 && ts.TotalDays <= 4)
{
switch (pickupDate.DayOfWeek)
{
case DayOfWeek.Thursday:
if (pickupDate.Hour >= 12)
{
switch (dropoffDate.DayOfWeek)
{
case DayOfWeek.Sunday:
return true;
case DayOfWeek.Monday:
if (dropoffDate.Hour <= 12)
{
return true;
}
return false;
}
}
break;
case DayOfWeek.Friday:
switch (dropoffDate.DayOfWeek)
{
case DayOfWeek.Sunday:
return true;
case DayOfWeek.Monday:
if (dropoffDate.Hour <= 12)
{
return true;
}
return false;
}
break;
case DayOfWeek.Saturday:
switch (dropoffDate.DayOfWeek)
{
case DayOfWeek.Sunday:
return true;
case DayOfWeek.Monday:
if (dropoffDate.Hour <= 12)
{
return true;
}
return false;
}
return false;
}
}
return false;
}
You definitely should refactor the dropoffDate out - because the code is duplicated 3 times! The simplest cleanup: I would introduce a function to check the pickupDate and another to check the dropoffDate:
private bool IsPickupWeekend(DateTime pickupDate)
{
switch (pickupDate.DayOfWeek)
{
case DayOfWeek.Thursday:
return pickupDate.Hour >= 12;
case DayOfWeek.Friday:
case DayOfWeek.Saturday:
return true;
}
}
return false;
}
private bool IsWeekendDropOff(DateTime dropoffDate)
{
switch (dropoffDate.DayOfWeek)
{
case DayOfWeek.Sunday:
return true;
case DayOfWeek.Monday:
if (dropoffDate.Hour <= 12)
{
return true;
}
return false;
}
return false;
}
And now your main function is a 2 liner:
if (ts.TotalDays >= 2 && ts.TotalDays <= 4)
{
return IsPickupWeekend(pickupDate) && IsWeekendDropOff(dropoffDate);
}
I think you could extract a method here:
private bool ValidateDropoff(DateTime dropoffDate)
{
switch (dropoffDate.DayOfWeek)
{
case DayOfWeek.Sunday:
return true;
case DayOfWeek.Monday:
return dropoffDate.Hour <= 12;
default:
return false;
}
}
if (ts.TotalDays >= 2 && ts.TotalDays <= 4)
{
var hour_limit = new Func<Boolean>(() => {
switch (dropoffDate.DayOfWeek)
{
case DayOfWeek.Sunday:
return true;
case DayOfWeek.Monday:
return dropoffDate.Hour <= 12;
default:
return false;
}
});
switch (pickupDate.DayOfWeek)
{
case DayOfWeek.Thursday:
if (pickupDate.Hour >= 12) return hour_limit();
break;
case DayOfWeek.Friday:
case DayOfWeek.Saturday:
return hour_limit();
default:
break;
}
}
return false;
Not much clearer, but here you go:
public bool ValidateWeekend(DateTime pickupDate, DateTime dropoffDate){
TimeSpan ts = dropoffDate.Subtract(pickupDate);
if (ts.TotalDays >= 2 && ts.TotalDays <= 4){
switch (pickupDate.DayOfWeek){
case DayOfWeek.Thursday:
if (pickupDate.Hour >= 12){
switch (dropoffDate.DayOfWeek){
case DayOfWeek.Sunday:
return true;
case DayOfWeek.Monday:
return dropoffDate.Hour <= 12;
}
}
break;
case DayOfWeek.Friday:
switch (dropoffDate.DayOfWeek){
case DayOfWeek.Sunday:
return true;
case DayOfWeek.Monday:
return dropoffDate.Hour <= 12;
}
break;
case DayOfWeek.Saturday:
switch (dropoffDate.DayOfWeek){
case DayOfWeek.Sunday:
return true;
case DayOfWeek.Monday:
return dropoffDate.Hour <= 12;
}
return false;
}
}
return false;
}
My first crack:
if (ts.TotalDays >= 2 && ts.TotalDays <= 4)
{
switch (pickupDate.DayOfWeek)
{
case DayOfWeek.Thursday:
case DayOfWeek.Friday:
case DayOfWeek.Saturday:
if (pickupDate.DayOfWeek == DayOfWeek.Thursday && pickupDate.Hour <= 12)
return false;
switch (dropoffDate.DayOfWeek)
{
case DayOfWeek.Sunday:
return true;
case DayOfWeek.Monday:
return dropoffDate.Hour <= 12;
}
return false;
default:
return false;
}
}
return false;
in the switch try
retrun (dropoffDate.DayOfWeek == DayOfWeek.Sunday && dropoffDate.Hour <= 12 || dropoffDate.DayOfWeek == DayOfWeek.Sunday)
I would do it something like this
public bool ValidateWeekend(DateTime pickupDate, DateTime dropoffDate)
{
TimeSpan ts = dropoffDate.Subtract(pickupDate);
if (ts.TotalDays >= 2 && ts.TotalDays <= 4)
{
switch (pickupDate.DayOfWeek)
{
case DayOfWeek.Thursday:
if (pickupDate.Hour >= 12)
{
reurn DayOfWeek(dropOffDate.DayOfWeek);
}
break;
case DayOfWeek.Friday, DayOfWeek.Saturday:
{
return DayOfWeek(dropOffDate.DayOfWeek);
}
}
}
return false;
}
public bool DayOfWeek(DateTime dropOffDate)
{
switch (dropoffDate.DayOfWeek)
{
case DayOfWeek.Sunday:
{
return true;
}
case DayOfWeek.Monday:
{
if (dropoffDate.Hour <= 12)
{
return true;
}
return false;
}
return false;
}
}
Here is my stab at it:
/// <summary>
/// Gets the weekend days.
/// </summary>
/// <returns></returns>
public List<DayOfWeek> GetWeekendDays()
{
List<DayOfWeek> days = new List<DayOfWeek>()
{
DayOfWeek.Thursday,
DayOfWeek.Friday,
DayOfWeek.Sunday
};
return days;
}
/// <summary>
/// Validates the weekend.
/// </summary>
/// <param name="pickupDate">The pickup date.</param>
/// <param name="dropoffDate">The dropoff date.</param>
/// <returns></returns>
public bool ValidateWeekend(DateTime pickupDate, DateTime dropoffDate)
{
bool isValid = false;
TimeSpan ts = dropoffDate.Subtract(pickupDate);
if (ts.TotalDays >= 2 && ts.TotalDays <= 4)
{
List<DayOfWeek> days = GetWeekendDays();
foreach (DayOfWeek day in days)
{
if(pickupDate.DayOfWeek == day)
{
isValid = ValidateDropOff(dropoffDate);
break;
}
}
}
return isValid;
}
/// <summary>
/// Validates the drop off.
/// </summary>
/// <param name="dropoffDate">The dropoff date.</param>
/// <returns></returns>
private static bool ValidateDropOff(DateTime dropoffDate)
{
bool isValidDropOff = (dropoffDate.DayOfWeek == DayOfWeek.Sunday);
if(dropoffDate.DayOfWeek == DayOfWeek.Monday)
{
if (dropoffDate.Hour <= 12)
{
isValidDropOff = true;
}
}
return isValidDropOff;
}
private readonly TimeSpan Midday = new TimeSpan(12, 0, 0);
public bool ValidateWeekend(DateTime pickupDate, DateTime dropoffDate)
{
TimeSpan lengthOfTrip = dropoffDate.Subtract(pickupDate);
if (lengthOfTrip.TotalDays < 2 || lengthOfTrip.TotalDays > 4)
return false;
return IsPickupDateConsideredWeekend(pickupDate) && IsDropoffDateConsideredWeekend(dropoffDate);
}
private bool IsPickupDateConsideredWeekend(DateTime pickupdate)
{
if (pickupdate.DayOfWeek == DayOfWeek.Thursday && pickupdate.TimeOfDay > Midday)
return true;
return false;
}
private bool IsDropoffDateConsideredWeekend(DateTime dropoffDate)
{
if (dropoffDate.DayOfWeek == DayOfWeek.Monday && dropoffDate.TimeOfDay <= Midday)
return true;
return false;
}
精彩评论