方法的模式或推荐的重构

时间:2012-06-22 10:06:43

标签: oop design-patterns

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

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 个答案:

答案 0 :(得分: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 
  }
}

这样,处理一种预订的代码与其他代码分开,这对可测试性和可维护性更好。

答案 1 :(得分: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;
    }
}

答案 2 :(得分: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个公共包装(这不太可扩展)。

答案 3 :(得分:1)

你说

  

“我无法将预订全部转换为相同的数据类型”

我说“为什么不”?

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

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