Hinweis: Das Codebeispiel ist in c # geschrieben, aber das sollte keine Rolle spielen. Ich habe c # als Tag angegeben, weil ich kein passenderes finde. Hier geht es um die Codestruktur.
Ich lese Clean Code und versuche, ein besserer Programmierer zu werden.
Ich habe oft Mühe, das Prinzip der Einzelverantwortung zu befolgen (Klassen und Funktionen sollten nur eines tun), insbesondere in Funktionen. Vielleicht ist mein Problem, dass "eine Sache" nicht genau definiert ist, aber immer noch ...
Ein Beispiel: Ich habe eine Liste von Fluffies in einer Datenbank. Es ist uns egal, was ein Fluffy ist. Ich möchte, dass eine Klasse Flaumiges wiederherstellt. Fluffies können sich jedoch nach einer bestimmten Logik ändern. Je nach Logik gibt diese Klasse die Daten aus dem Cache zurück oder ruft die neuesten Daten aus der Datenbank ab. Wir könnten sagen, dass es mit Flusen umgeht, und das ist eine Sache. Nehmen wir zum Vereinfachen an, dass geladene Daten eine Stunde lang gültig sind und dann neu geladen werden müssen.
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()
scheint mir in Ordnung zu sein. Der Benutzer bittet um einige Flaumigkeiten, wir stellen sie zur Verfügung. Ich werde sie bei Bedarf aus der Datenbank wiederherstellen, aber das kann als Teil des Erhalts der Fluffies angesehen werden (natürlich ist das etwas subjektiv).
NeedsReload()
scheint auch richtig. Überprüft, ob die Fluffies neu geladen werden müssen. UpdateNextLoad ist in Ordnung. Aktualisiert die Zeit für das nächste Neuladen. Das ist definitiv eine einzige Sache.
Ich fühle jedoch, was LoadFluffies()
nicht als eine einzige Sache beschrieben werden kann. Es ruft die Daten aus der Datenbank ab und plant das nächste Neuladen. Es ist schwer zu argumentieren, dass das Berechnen der Zeit für das nächste Neuladen Teil des Erhalts der Daten ist. Ich kann jedoch keinen besseren Weg finden, dies zu tun (das Umbenennen der Funktion in ist LoadFluffiesAndScheduleNextLoad
möglicherweise besser, aber es macht das Problem nur offensichtlicher).
Gibt es eine elegante Lösung, um diese Klasse wirklich nach dem SRP zu schreiben? Bin ich zu pedantisch?
Oder macht meine Klasse nicht wirklich nur eine Sache?
DateTime.UtcNow
Sie ihn, um Umstellungen auf Sommerzeit oder sogar eine Änderung der aktuellen Zeitzone zu vermeiden.