Google Calendar API查询函数重复代码重构方案咨询
重构Google Calendar API查询代码以避免重复
嘿,这个问题我太懂了!完全不用复制三次GetMeetings函数,核心思路就是把变化的部分(私有扩展属性的组合)和不变的部分(认证、请求执行、结果转换)分离。这里有两个实用的重构方案,看你偏好哪种:
方案1:核心函数+重载方法(最直观简洁)
首先把原来的GetMeetings改成一个接受私有扩展属性数组的核心函数,把重复的逻辑都放在这里:
// 核心复用函数,处理通用逻辑 private List<Meeting> GetMeetingsCore(DateTime minTime, DateTime maxTime, string[] privateExtendedProperties) { CalendarService service = AuthenticateAccount(CalendarId); EventsResource.ListRequest request = new EventsResource.ListRequest(service, CalendarId) { TimeMin = minTime, TimeMax = maxTime, TimeZone = "Europe/Amsterdam", PrivateExtendedProperty = privateExtendedProperties, }; Events events = request.Execute(); List<Meeting> meetingList = new List<Meeting>(); foreach (var item in events.Items) { // 这里是你原来的Meeting对象转换逻辑... } return meetingList; }
然后再封装几个对外的重载方法,对应你需要的三种查询场景,这样外部调用的时候完全不用关心属性拼接的细节:
// 查询仅带UserId属性的会议 public List<Meeting> GetMeetingsByUserId(DateTime minTime, DateTime maxTime, string userId) { return GetMeetingsCore(minTime, maxTime, new[] { $"UserId={userId}" }); } // 查询仅带ClassroomId属性的会议 public List<Meeting> GetMeetingsByClassroomId(DateTime minTime, DateTime maxTime, int classroomId) { return GetMeetingsCore(minTime, maxTime, new[] { $"ClassroomId={classroomId}" }); } // 查询同时带两个属性的会议(保留你原来的函数签名,兼容现有调用) public List<Meeting> GetMeetings(DateTime minTime, DateTime maxTime, string userId, int classroomId) { return GetMeetingsCore(minTime, maxTime, new[] { $"ClassroomId={classroomId}", $"UserId={userId}" }); }
这种方式的好处是代码结构清晰,每个重载方法只负责自己的属性组合逻辑,核心函数专注于通用的API请求和结果处理,完全避免了代码重复。
方案2:用枚举标记控制属性组合(更灵活扩展)
如果未来可能需要增加更多的过滤属性,用枚举标记的方式会更灵活:
首先定义一个带[Flags]特性的枚举,用来标记需要启用的过滤条件:
[Flags] public enum MeetingFilter { None = 0, IncludeUserId = 1, IncludeClassroomId = 2, IncludeBoth = IncludeUserId | IncludeClassroomId }
然后修改核心函数,根据枚举标记来动态生成私有扩展属性:
public List<Meeting> GetMeetings(DateTime minTime, DateTime maxTime, MeetingFilter filterType, string userId = null, int classroomId = 0) { var properties = new List<string>(); if (filterType.HasFlag(MeetingFilter.IncludeUserId) && !string.IsNullOrEmpty(userId)) { properties.Add($"UserId={userId}"); } if (filterType.HasFlag(MeetingFilter.IncludeClassroomId) && classroomId != 0) { properties.Add($"ClassroomId={classroomId}"); } CalendarService service = AuthenticateAccount(CalendarId); EventsResource.ListRequest request = new EventsResource.ListRequest(service, CalendarId) { TimeMin = minTime, TimeMax = maxTime, TimeZone = "Europe/Amsterdam", PrivateExtendedProperty = properties.ToArray(), }; Events events = request.Execute(); List<Meeting> meetingList = new List<Meeting>(); foreach (var item in events.Items) { // 转换逻辑... } return meetingList; }
调用的时候就可以通过枚举来指定查询类型:
// 仅查UserId的会议 var userMeetings = GetMeetings(minTime, maxTime, MeetingFilter.IncludeUserId, userId: userId); // 仅查ClassroomId的会议 var classroomMeetings = GetMeetings(minTime, maxTime, MeetingFilter.IncludeClassroomId, classroomId: classroomId); // 查同时带两个属性的会议 var bothMeetings = GetMeetings(minTime, maxTime, MeetingFilter.IncludeBoth, userId, classroomId);
这个方案的优势是扩展性强,以后要加新的私有属性过滤,只需要给枚举加新值,再在核心函数里加对应的判断逻辑就行。
推荐选择
如果你的需求就固定这三种场景,方案1是最优的,代码更简洁直观,维护成本低。如果未来可能有更多的过滤组合需求,方案2会更合适。
内容的提问来源于stack exchange,提问作者Barry The Wizard
相关产品推荐
相关产品推荐

