Ich habe eine Codebasis geerbt, in der es eine Menge Code gibt, der ungefähr so aussieht:
SomeDataAdapter sda = new SomeDataAdapter();
sda.UpdateData(DataTable updateData);
Und dann wird sda nie wieder benutzt.
Ist das ein Codegeruch, der darauf hinweist, dass diese Methoden stattdessen statische Klassenmethoden sein sollten?
code-smell
static-methods
Shane Wealti
quelle
quelle
Antworten:
Ich würde es als Architekturgeruch betrachten, dass UpdateData wahrscheinlich zu einer 'Service'-Klasse gehören sollte.
Wo die Daten ein Apple sind. Wobei AppleAdapter eine Service- / Business-Intelligence-Klasse ist. Wobei AppleService ein Singleton-Verweis auf einen AppleAdapter ist, der außerhalb der aktuellen Methode vorhanden ist.
Ich denke nicht, dass das, was Sie tun, notwendigerweise falsch ist, aber wenn SomeDataAdapter tatsächlich eine Art zustandslosen Geschäftsdienst darstellt, dann wäre ein Singleton die beste Vorgehensweise dafür. Ich hoffe, das hilft! Das angegebene Beispiel ist eine hervorragende Möglichkeit, um sicherzustellen, dass der _appleService nicht in Konflikt gerät, wenn er null ist und zwei oder mehr Threads gleichzeitig auf ihn zugreifen.
Weißt du was? Wenn SomeDataAdapter ein ADO-IDbDataAdapter ist (was mit ziemlicher Sicherheit der Fall ist), ignorieren Sie diese gesamte Antwort!
: P
Ich habe keine Berechtigung, der ursprünglichen Frage einen Kommentar hinzuzufügen, aber wenn Sie angeben könnten, wo dieser Code vorhanden ist.
Wenn dieser Code eine benutzerdefinierte Implementierung eines IDbDataAdapters darstellt und UpdateData eine IDbConnection, einen IDbCommand erstellt und alles hinter den Kulissen verkabelt, dann würde ich keinen Codegeruch in Betracht ziehen, da es sich jetzt um Streams und andere handelt Dinge, die entsorgt werden müssen, wenn wir damit fertig sind.
quelle
Ich denke, dieses Problem geht noch tiefer. Selbst wenn Sie es in eine statische Methode umgestalten, erhalten Sie überall Code, in dem Sie eine einzelne statische Methode aufrufen. Was meiner Meinung nach Code-Geruch ist. Es könnte darauf hindeuten, dass Sie eine wichtige Abstraktion vermissen. Möglicherweise möchten Sie einen Code erstellen, der einige Vor- und Nachbearbeitungen vornimmt und gleichzeitig die Möglichkeit bietet, die Zwischenabläufe zu ändern. Diese Vor- und Nachbearbeitung wird die gemeinsamen Aufrufe enthalten, während das dazwischenliegende von der konkreten Implementierung abhängt.
quelle
So'ne Art. In der Regel bedeutet dies, dass Sie eine Funktion weitergeben möchten und die Sprache Ihrer Wahl dies nicht zulässt. Es ist etwas ungeschickt und unelegant, aber wenn Sie in einer Sprache ohne erstklassige Funktionen festsitzen, können Sie nicht viel tun.
Wenn keines dieser Objekte als Argumente an andere Funktionen übergeben wird, können Sie sie in statische Methoden umwandeln, und es ändert sich nichts.
quelle
fn x => x + 1
undnew Function<Integer, Integer>() { public Integer eval(Integer x) { return x + 1; }};
oder die Beschränkung auf ein paar hartkodierte und äußerst nützliche Funktionen , wenn Ihre Sprache nicht mindestens einen Syntaxzucker hat .fn x => x + 1
syntaktischer Zucker nicht seinnew Function<Integer, Integer>() { public Integer eval(Integer x) { return x + 1; }}
? Ok, vielleicht meinst du, wenn man in einer Sprache ohne diese Art von syntaktischem Zucker steckt.Wenn der Haltestatus eine bestimmte Klasse nützlicher, funktionaler… wiederverwendbar macht, dann nein. Aus irgendeinem Grund kommt das Befehlsentwurfsmuster in den Sinn; dieser Grund ist sicherlich nicht der Wunsch, Robert Harvey ertrinken zu lassen.
quelle
Definieren Sie "häufig". Wie oft instanziieren Sie das Objekt? Viel - wahrscheinlich nicht?
Es gibt wahrscheinlich größere Probleme in Ihrem System. Wenn Sie statisch werden, wird dem Programmierer klarer mitgeteilt, dass sich der interne Zustand des Objekts nicht ändert - großartig.
Wenn der Zustand jedoch durcheinander gebracht wird und Sie andere Dinge statisch machen müssen, um das Erste statisch zu machen, müssen Sie sich fragen, welche Teile statisch sein müssen und welche nicht.
Ja, es ist ein Codegeruch, nur ein kleiner.
quelle
Machen Sie es zu einer statischen Methode und fahren Sie fort. An statischen Methoden ist nichts auszusetzen. Sobald ein Verwendungsmuster auftritt, können Sie sich Gedanken über die Abstraktion des Musters machen.
quelle
Der Geruch hier ist, dass dies prozeduraler Code ist, der (minimal) in Objekte eingeschlossen ist.
Es muss einen Grund geben warum Sie diese Operation in der Datentabelle ausführen möchten, aber anstatt diese Operation mit anderen verwandten Operationen zu modellieren, die eine bestimmte Semantik aufweisen (dh eine gemeinsame Bedeutung haben), hat der Autor einfach eine neue Prozedur in einer neuen Prozedur gestartet Klasse & nannte es.
In einer funktionalen Sprache würden Sie so vorgehen;), aber im OO-Paradigma möchten Sie modellieren eine Abstraktion , die diese Operation einschließt. Dann würden Sie OO-Techniken verwenden, um dieses Modell zu verfeinern und eine Reihe verwandter Operationen bereitzustellen, die einige Semantik bewahren.
Der Hauptgeruch hier ist also, dass der Autor Klassen verwendet, wahrscheinlich weil der Compiler dies benötigt, ohne Operationen in einem konzeptuellen Modell zu organisieren.
Übrigens: Passen Sie immer auf, wenn Sie sehen, dass das Programm anstelle des Problembereichs modelliert wird . Dies ist ein Zeichen dafür, dass das Design von mehr Überlegungen profitieren könnte. Mit anderen Worten, achten Sie auf Klassen, die alle "xAdaptor" und "xHandler" und "xUtility" sind und normalerweise an ein anämisches Domänenmodell gebunden sind . Es bedeutet, dass jemand nur Code bündelt, um die Implementierung zu vereinfachen, anstatt die Konzepte zu modellieren, die er implementieren möchte.
quelle