C#不同类复用同名方法实现差异化逻辑的优化咨询
优化方案:让生日提醒方法适配多场景,避免重复代码
核心问题拆解
当前RemindPersonForBirthday方法在两种场景下需求矛盾:
- 每日循环(
InfinityLoop调用):需要遍历所有用户,检查生日/次日生日并发送提醒 - 用户选日期(
PickDate调用):只需要检查当前操作的用户,验证选中日期是否触发提醒
通过拆分核心逻辑+参数控制范围的方式,既能复用代码,又能满足不同场景的需求。
1. 重构ReminderBack类
将单个用户的生日检查逻辑抽离为私有方法,公共方法通过参数控制检查范围:
public static class ReminderBack { // 核心逻辑:检查单个用户的生日并发送对应消息 private static async Task CheckSingleUserBirthday(ITelegramBotClient botClient, Update update, string userName, DateTime userBirthDate) { var currDate = DateTime.Today; if (userBirthDate.Month == currDate.Month && userBirthDate.Day == currDate.Day) { var message = $"Today is {userName}'s birthday!"; await PRTelegramBot.Helpers.Message.Send(botClient, update, message); } else if (userBirthDate.Month == currDate.Month && userBirthDate.Day == currDate.Day + 1) { var message = $"{userName}'s birthday is tomorrow!"; await PRTelegramBot.Helpers.Message.Send(botClient, update, message); } } // 公共方法:支持检查单个用户或所有用户 public static async Task RemindPersonForBirthday(ITelegramBotClient botClient, Update update, string targetUserName = null) { var cache = update.GetCacheData<UserCache>(); if (!string.IsNullOrEmpty(targetUserName)) { // 只检查指定用户 if (cache.ScheduleDict.TryGetValue(targetUserName, out var birthDate)) { await CheckSingleUserBirthday(botClient, update, targetUserName, birthDate); } return; } // 遍历所有用户(默认逻辑,适配每日循环) foreach (var user in cache.ScheduleDict) { await CheckSingleUserBirthday(botClient, update, user.Key, user.Value); } } }
2. 修改InfinityLoop的调用逻辑
保持原有遍历所有用户的逻辑,直接调用无参重载:
public static async Task StartReminderLoop(ITelegramBotClient botClient, Update update) { while (true) { if (_lastCheckDate.Day != DateTime.Now.Day) { // 无参调用,遍历所有用户 await ReminderBack.RemindPersonForBirthday(botClient, update); _lastCheckDate = DateTime.Now; } await Task.Delay(CheckInterval); } }
3. 修改CalendarCommandHandler.PickDate的调用逻辑
传入当前操作的用户名,只检查该用户:
public static async Task PickDate(ITelegramBotClient botClient, Update update) { if (update.CallbackQuery?.Data is null) { return; } try { var command = InlineCallback<CalendarTCommand>.GetCommandByCallbackOrNull(update.CallbackQuery.Data); var data = command.Data.Date; var message = $"Picked date: <b>{data:dd.MM.yyyy}</b>"; await PRTelegramBot.Helpers.Message.Edit(botClient, update, message); // 缓存日期 var cache = update.GetCacheData<UserCache>(); cache.DateT = data; var targetUserName = cache.PersonName ?? "unknown"; CacheCommand.UpdateCache(update, targetUserName, cache.DateT); // 传入当前用户名,只检查该用户 await ReminderBack.RemindPersonForBirthday(botClient, update, targetUserName); } catch (Exception ex) { Console.WriteLine(ex); } }
额外优化建议
- 若后续新增场景,可考虑用策略模式进一步解耦,当前场景参数控制已足够简洁
- 给
CheckSingleUserBirthday添加日志,方便排查问题 - 已处理
userName为空的边界情况,确保逻辑健壮性
内容的提问来源于stack exchange,提问作者szymptom
相关产品推荐
相关产品推荐

