Разделите загрузку пользователей, построение поздравления и запись файлов; зависимости передавайте через конструктор, а асинхронный запрос ожидайте через await.
Переписывание фрагмента кода в соответствии с принципами SOLID
Разделите загрузку пользователей, построение поздравления и запись файлов; зависимости передавайте через конструктор, а асинхронный запрос ожидайте через await.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо улучшить данный пример, устранив нарушения SOLID и сделав его более поддерживаемым и читаемым. Примените подходящие изменения к структуре класса и его методам.
public class BirthdayTemplateProcessor
{
public static UserDal UserRepository { get; set; } = new UserDal();
public static void GenerateTemplates(int[] ids)
{
string[] names = UserRepository.Query()
.Where(u => ids.Contains(u.Id))
.Select(u => u.UserName)
.ToArrayAsync().Result;
string messageTemplate = "Hello, dear {0}. Happy Birthday!";
string directoryPath = "C://templates/birthdays/";
foreach (var name in names)
{
System.IO.File.WriteAllText(directoryPath + name, string.Format(messageTemplate, name));
}
}
}
Ответ
Разделите загрузку пользователей, построение поздравления и запись файлов; зависимости передавайте через конструктор, а асинхронный запрос ожидайте через await.
Минимальная схема оркестратора с явно заданными контрактами зависимостей:
public record Recipient(int Id, string Name);
public interface IRecipients {
Task<IReadOnlyList<Recipient>> LoadAsync(int[] ids);
}
public interface ITemplateStore {
Task SaveAsync(int id, string text);
}
public sealed class BirthdayProcessor(IRecipients users, ITemplateStore store)
{
public async Task GenerateAsync(int[] ids)
{
foreach (var user in await users.LoadAsync(ids))
await store.SaveAsync(user.Id,
$"Hello, dear {user.Name}. Happy Birthday!");
}
}
Хранилище получает каталог из конфигурации и формирует безопасное имя по ID, а не по пользовательскому имени. Так устраняются коллизии имён и обход каталогов. .Result и изменяемое static-свойство больше не нужны. Отдельный интерфейс форматтера полезен при нескольких шаблонах, но не обязателен ради самого SOLID.