Примітка: Зразок коду написаний c #, але це не має значення. Я поставив c # як тег, тому що не можу знайти більш підходящого. Йдеться про структуру коду.
Я читаю «Чистий код» і намагаюся стати кращим програмістом.
Мені часто буває важко дотримуватися принципу єдиної відповідальності (класи та функції повинні виконувати лише одне), особливо у функціях. Можливо, моя проблема полягає в тому, що "одна річ" недостатньо визначена, але все ж ...
Приклад: у мене є список Fluffies в базі даних. Нам не байдуже, що таке Пухнастий. Я хочу, щоб клас відновив пухнастики. Однак пушинки можуть змінюватися за певною логікою. Залежно від певної логіки, цей клас поверне дані з кешу або отримає останні дані з бази даних. Можна сказати, що вона управляє пухнастиками, і це одне. Щоб зробити це просто, скажімо, що завантажені дані корисні протягом години, а потім вони повинні бути перезавантажені.
class FluffiesManager
{
private Fluffies m_Cache;
private DateTime m_NextReload = DateTime.MinValue;
// ...
public Fluffies GetFluffies()
{
if (NeedsReload())
LoadFluffies();
return m_Cache;
}
private NeedsReload()
{
return (m_NextReload < DateTime.Now);
}
private void LoadFluffies()
{
GetFluffiesFromDb();
UpdateNextLoad();
}
private void UpdateNextLoad()
{
m_NextReload = DatTime.Now + TimeSpan.FromHours(1);
}
// ...
}
GetFluffies()
мені здається нормальним. Користувач просить трохи пушинок, ми їх надаємо. Якщо потрібно, відновіть їх із БД, але це може вважатися частиною отримання пухнастиків (звичайно, це дещо суб'єктивно).
NeedsReload()
здається, що теж. Перевіряє, чи потрібно нам перезавантажувати пушинки. UpdateNextLoad добре. Оновляється час для наступного перезавантаження. це однозначно одна річ.
Однак я відчуваю, що LoadFluffies()
робити не можна охарактеризувати як одну єдину річ. Він отримує дані з Бази даних і планує наступне перезавантаження. Важко заперечити, що обчислення часу для наступного перезавантаження є частиною отримання даних. Однак я не можу знайти кращого способу це зробити (перейменування функції на LoadFluffiesAndScheduleNextLoad
краще, але це просто робить проблему більш очевидною).
Чи є елегантне рішення дійсно написати цей клас відповідно до SRP? Я занадто педантичний?
А може, мій клас насправді не займається однією справою?
DateTime.UtcNow
щоб уникнути зміни переходу на літній час або навіть зміни поточного часового поясу.