2

我写了一个看起来像这样的方法:

public TimeSlotList processTimeSlots (DateTime startDT, DateTime endDT, string bookingType, IList<Booking> normalBookings, GCalBookings GCalBookings, List<DateTime> otherApiBookings) {
{

..... common process code ......

    while (utcTimeSlotStart < endDT)
    {

        if (bookingType == "x")
        {
            //process normal bookings using IList<Booking> normalBookings

        }
        else if (bookingType == "y") {

            //process google call bookings using GCalBookings GCalBookings
        }
        else if (bookingType == "z" {

            //process other apibookings using List<DateTime> otherApiBookings

        }

    }

}

所以我从 3 个不同的地方调用它,每次传递一个不同的预订类型,每个案例传递我有兴趣处理的预订,以及 2 个不用于此预订类型的空对象。

我无法将所有预订都纳入相同的数据类型,这会使这更容易,并且每种预订类型都需要以不同的方式处理,所以我不确定如何改进这一点。

4

4 回答 4

3

如果您可以更改调用代码,我建议为每个不同的预订处理器创建单独的类,并使用一个公共基类:

public abstract class BookingProcessor<TBookings> {
  public TimeSlotList ProcessTimeSlots(DateTime startDT, DateTime endDT, TBookings bookings) {
    // ..... common process code ......
    while (utcTimeSlotStart < endDT) {
      ProcessTimeSlots(utcTimeSlotStart, bookings);
      // ...
    }
  }
  protected abstract ProcessTimeSlots(DateTime utcTimeSlotStart, TBookings bookings);
}

特定的预订处理器遵循以下模式:

public class NormalBookingsProcessor : BookingProcessor<IList<Booking>> {
  protected override ProcessTimeSlots(DateTime utcTimeSlotStart, IList<Booking> bookings) {
    // process normal bookings using IList<Booking> normalBookings 
  }
}

这样,处理一种类型的预订的代码与其他类型的代码是分开的,这更有利于可测试性和可维护性。

于 2012-06-22T10:30:32.607 回答
1
// Just do extract method for each booking type processign logic
// also use typed booking type (enum) to leverage switch() conditional flow
// rather than multiple nested if/else

public enum BookingType
{
    X,
    Y,
    Z
}

private void EntryPoint(DateTime startDT, 
    DateTime endDT, 
    string bookingType, 
    IList<Booking> normalBookings, 
    GCalBookings GCalBookings, 
    List<DateTime> otherApiBookings)
{

    // common logic

    BookingType type = (BookingType)Enum.Parse(bookingType.ToUpperInvariant(), typeof(BookingType));

    switch (type)
    {
        case BookingType.X:
            ProcessNormalBookings(startDt, endDt, normalBookings);
            break;
        case BookingType.Y:
            ProcessGcCalBookings(startDt, endDt, GCalBookings);
            break;
        case BookingType.Z:
            ProcessOtherApiBookings(startDt, endDt, otherApiBookings);
            break;
    }
}
于 2012-06-22T10:13:33.750 回答
1

将这 3 个数据结构变成预订类,都继承自具有接口的公共父级:

public TimeSlotList processTimeSlots (DateTime startDT, DateTime endDT)

或者

看到类似但更好解释的答案https://stackoverflow.com/a/11154505/537980

或者

写3个例程

public TimeSlotList processTimeSlots_Normal (DateTime startDT, DateTime endDT, string bookingType, IList<Booking> normalBookings) {
{
    common_process_code(local_vars);

    //process normal bookings using IList<Booking> normalBookings
}

等等

或者

将原始文件设为私有,并编写 3 个公共包装器(扩展性较差)。

于 2012-06-22T10:23:30.080 回答
1

你说

“我无法将预订全部归入相同的数据类型”

我说“为什么不”?

如果在最低级别,这些预订对象从其他类型继承,则使用组合并将这些对象作为 AbstractBooking 类的三个子类(NormalBooking、GoogleBooking、OtherBooking)的成员。

在这一点上,我认为您根据您的帖子知道,您可以在每个子类中拥有自定义预订代码。

于 2012-06-22T13:32:54.877 回答