Verwenden Sie eine leere Zeichenfolge, null oder entfernen Sie leere Eigenschaften in der API-Anforderung / Antwort

25

Was ist der ideale Weg, um beim Übertragen von Objekten über eine API wie im schemenlosen JSON-Format nicht vorhandene Zeichenfolgeneigenschaften zurückzugeben? Ich weiß, dass es verschiedene Möglichkeiten gibt, dies zu tun, wie in den Beispielen in den unten aufgelisteten Links.

Ich bin mir sicher, dass ich in der Vergangenheit null verwendet habe, aber ich habe keinen guten Grund, dies zu tun. Es scheint einfach zu sein, beim Umgang mit der Datenbank null zu verwenden. Die Datenbank scheint jedoch ein Implementierungsdetail zu sein, das die Partei auf der anderen Seite der API nicht betreffen sollte. ZB verwenden sie wahrscheinlich einen schemenlosen Datenspeicher, in dem nur Eigenschaften mit Werten (ungleich Null) gespeichert werden.

stringCodebezogen erleichtert die Einschränkung, dass Zeichenfolgenfunktionen nur mit einem Typ funktionieren ( dh nicht mit Null), den Nachweis. Null zu vermeiden, ist auch ein Grund, ein OptionObjekt zu haben. Wenn der Code, der Request / Response erzeugt, nicht null verwendet, wird der Code auf der anderen Seite der API vermutlich auch nicht dazu gezwungen, null zu verwenden.

Ich mag eher die Idee, eine leere Zeichenfolge zu verwenden, um die Verwendung von null zu vermeiden. Ein Argument, das ich für die Verwendung von null und gegen die leere Zeichenfolge gehört habe, ist, dass leere Zeichenfolge bedeutet, dass die Eigenschaft vorhanden ist. Obwohl ich den Unterschied verstehe, frage ich mich auch, ob dies das einzige Implementierungsdetail ist und ob die Verwendung von entweder null oder einer leeren Zeichenfolge einen Unterschied im wirklichen Leben darstellt. Ich frage mich auch, ob eine leere Zeichenfolge einem leeren Array entspricht.

Was ist der beste Weg, um diese Bedenken auszuräumen? Kommt es auf das Format des zu übertragenden Objekts an (Schema / schemenlos)?

imel96
quelle
2
Beachten Sie außerdem, dass Oracle leere Zeichenfolgen und Nullzeichenfolgen auf dieselbe Weise behandelt. Und genau da: Wie können Sie auf einem Fragebogen auf Papier zwischen einer nicht gegebenen Antwort und einer Antwort, die aus einer leeren Zeichenfolge besteht, unterscheiden?
Bernhard Hiller
Wenn Sie die Vererbung verwenden, ist es einfach zu sagen if( value === null) { use parent value; } . Wenn Sie den untergeordneten Wert jedoch auch auf eine leere Zeichenfolge festlegen (z. B. den übergeordneten Standardwert mit Leerzeichen überschreiben), wie können Sie den Wert dann "erneut erben"? Wenn Sie den Wert auf null setzen, bedeutet dies für mich, dass Sie diesen Wert deaktivieren, damit Sie den übergeordneten Wert verwenden können.
Frank Forte
Da "Leere Eigenschaft entfernen" auch der Grund für das "Vermeiden" eines null(es ist wahr, dass dies nullals solches vermieden wird) ist, bedeutet der Fragesteller "Nicht-Null zurückgeben" [Objekt] (dh: leerer String, leeres Array usw.), wenn sie schreibe "vermeiden".
cellepo

Antworten:

18

TLDR; NULL-Eigenschaften entfernen

Das erste, was zu beachten ist, ist, dass Anwendungen an ihren Rändern nicht objektorientiert sind (und auch nicht funktionieren, wenn sie in diesem Paradigma programmiert werden). Der JSON, den Sie erhalten, ist kein Objekt und sollte nicht als solches behandelt werden. Es sind nur strukturierte Daten, die in ein Objekt umgewandelt werden können (oder auch nicht). Im Allgemeinen sollte kein eingehendes JSON als Geschäftsobjekt als vertrauenswürdig eingestuft werden, bis es als solches validiert wurde. Allein die Tatsache, dass es deserialisiert wurde, macht es nicht gültig. Da JSON im Vergleich zu Back-End-Sprachen auch über eingeschränkte Grundelemente verfügt, lohnt es sich häufig, ein JSON-ausgerichtetes DTO für die eingehenden Daten zu erstellen. Verwenden Sie dann das DTO, um ein Geschäftsobjekt (oder einen Fehler beim Ausführen der API-Operation) zu erstellen.

Wenn Sie JSON nur als Übertragungsformat betrachten, ist es sinnvoller, nicht festgelegte Eigenschaften wegzulassen. Es ist weniger über das Kabel zu senden. Wenn Ihre Back-End-Sprache standardmäßig keine Nullen verwendet, können Sie Ihren Deserializer möglicherweise so konfigurieren, dass ein Fehler auftritt. Zum Beispiel übersetzt mein allgemeines Setup für Newtonsoft.Json null / fehlende Eigenschaften nur in / von F # option-Typen und führt ansonsten zu Fehlern. Dies gibt eine natürliche Darstellung, welche Felder optional sind (solche mit optionTyp).

Verallgemeinerungen bringen Sie wie immer nur so weit. Es gibt wahrscheinlich Fälle, in denen eine Standard- oder Null-Eigenschaft besser passt. Es geht jedoch nicht darum, Datenstrukturen am Rand Ihres Systems als Geschäftsobjekte zu betrachten. Geschäftsobjekte sollten bei erfolgreicher Erstellung Geschäftsgarantien tragen (z. B. mindestens 3 Zeichen nennen). Datenstrukturen, die aus der Leitung gezogen wurden, haben jedoch keine wirklichen Garantien.

Kasey Speakman
quelle
3
Während die meisten modernen Serialisierer optionale Felder haben, ist das Weglassen von Nullen in der Antwort nicht immer eine gute Idee, da die Behandlung von nullbaren Feldern zusätzliche Komplexität mit sich bringen kann. So ist es wirklich fallabhängig , je nachdem , wie die Serialisierung Bibliothek Griffe nullables, und ob die (potentiellen) zusätzliche Komplexität dieser nullables Handling ist wirklich lohnt sich, ein paar Bytes pro Anfrage zu speichern. Sie müssen hart arbeiten, um Ihre Geschäftsfälle zu analysieren.
Chris Cirefice
@ ChrisCirefice Ja, ich glaube, der letzte Absatz behandelt das. Es gibt Fälle, in denen es besser ist, unterschiedliche Strategien anzuwenden.
Kasey Speakman
Ich bin damit einverstanden, dass JSON nur als Übertragungsformat verwendet wird und keine Objekte wie CORBA durch die Drähte leitet. Ich stimme auch zu, dass Eigenschaften hinzugefügt und entfernt werden können. Darstellungen können sich ändern, Steuerelemente können sich ändern, insbesondere im Web.
imel96
15

Update: Ich habe die Antwort ein wenig überarbeitet, da dies zu Verwirrung führen kann.


Mit einer leeren Zeichenfolge zu gehen, ist ein definitives Nein. Leerer String ist immer noch ein Wert, er ist nur leer. Mit einem Konstrukt, das nichts darstellt, sollte kein Wert angegeben werden null.

Aus Sicht des API-Entwicklers gibt es nur zwei Arten von Eigenschaften:

  • erforderlich (diese MÜSSEN einen Wert ihres spezifischen Typs haben und DÜRFEN NIEMALS leer sein),
  • optional (diese KÖNNEN einen Wert ihres spezifischen Typs enthalten, KÖNNEN aber auch enthalten null.

Dies macht ganz klar, dass, wenn eine Eigenschaft obligatorisch ist, dh. erforderlich, kann es nie sein null.

Sollte andererseits eine optionale Eigenschaft eines Objekts nicht gesetzt und leer gelassen werden, ziehe ich es vor, sie trotzdem mit dem nullWert in der Antwort zu belassen . Nach meiner Erfahrung ist es für die API-Clients einfacher, das Parsen zu implementieren, da sie nicht prüfen müssen, ob eine Eigenschaft tatsächlich vorhanden ist oder nicht, da sie immer vorhanden ist, und sie können die Antwort einfach in ihr benutzerdefiniertes DTO konvertieren und nullWerte behandeln als optional.

Dynamisches Einschließen / Entfernen von Feldern aus den Reaktionskräften, einschließlich zusätzlicher Bedingungen für die Clients.


Stellen Sie in jedem Fall sicher, dass die Informationen konsistent und gut dokumentiert sind. Auf diese Weise spielt es keine Rolle, was Sie für Ihre API verwenden, solange das Verhalten vorhersehbar ist.

Andy
quelle
Ja, leere Zeichenfolge ist ein Wert und ich verwende nullfür Referenzen. Das Mischen von Werten mit Referenzen ist mir ein Anliegen. Wie unterscheidet man optionale Felder nullvon nicht optionalen Stringfeldern mit nullWert? Wird der Parser nicht zerbrechlicher, wenn das Vorhandensein von Eigenschaften nicht überprüft wird?
imel96
2
@ imel96 Nicht optionale Felder dürfen NIE null sein. Wenn etwas nicht optional ist, MUSS es immer einen Wert (seines spezifischen Typs) enthalten.
Andy
3
Dies. Als häufiger Konsument von APIs hasse ich es, wenn ich mich mit "dynamischen" Strukturen auseinandersetzen muss, die auf mich zurückkommen, auch wenn ein optionales Feld weggelassen wird. (Ich bin mir auch einig, dass es einen großen Unterschied zwischen einem ZLS und einem Null gibt). Ich würde gerne den ganzen Tag Nullwerte akzeptieren. Als API-Autor ist es eines meiner Ziele, den Kundenverbrauch so einfach wie möglich zu gestalten, und das bedeutet, immer die erwarteten Datenstrukturen zu haben.
Jleach
@DavidPacker Wenn ich das richtig verstehe, geben Sie nullan, dass der Wert optional ist. Wenn Sie also ein Objekt definieren, das eine nicht optionale Zeichenfolgeeigenschaft hat und der Verbraucher diese Eigenschaft nicht hat, muss er eine leere Zeichenfolge für diese Eigenschaft senden. Ist das richtig?
imel96
2
@GregoryNisbet Tu das bitte nicht. Das macht keinen Sinn.
Andy
3

null Die Verwendung ist abhängig von der Anwendung / Sprache

Letztendlich wird die Wahl, ob Sie nullals gültigen Anwendungswert verwenden möchten oder nicht, weitgehend von Ihrer Anwendung und Ihrer Programmiersprache / Schnittstelle / Kante bestimmt.

Grundsätzlich würde ich empfehlen, unterschiedliche Typen zu verwenden, wenn es unterschiedliche Werteklassen gibt. nullDies kann eine Option sein, wenn Ihre Schnittstelle dies zulässt und Sie nur zwei Klassen einer Eigenschaft darstellen möchten. Das Weglassen einer Eigenschaft kann eine Option sein, wenn Ihre Benutzeroberfläche oder Ihr Format dies zulässt. Ein neuer Aggregattyp (Klasse, Objekt, Nachrichtentyp) kann eine weitere Option sein.

Wenn dies für Ihr Zeichenfolgenbeispiel in der Programmiersprache ist, würde ich mir ein paar Fragen stellen.

  1. Plant ich, zukünftige Arten von Werten hinzuzufügen? Wenn ja, ist eine Optionwahrscheinlich besser für Ihr Interface-Design.
  2. Wann muss ich Verbraucheranrufe validieren? Statisch? Dynamisch? Vor? Nach? Überhaupt? Wenn Ihre Programmiersprache dies unterstützt, können Sie die Vorteile der statischen Typisierung nutzen, da dadurch die Menge an Code vermieden wird, die Sie zur Validierung erstellen müssen. OptionFüllt diesen Fall wahrscheinlich am besten aus, wenn Ihre Zeichenfolge nicht nullwertfähig war. Allerdings müssen Sie wahrscheinlich nulltrotzdem die Benutzereingabe auf einen Zeichenfolgenwert überprüfen, sodass ich wahrscheinlich auf die erste Fragezeile zurückgreifen möchte: Wie viele Arten von Werten möchte ich darstellen?
  3. Ist nullbezeichnend für einen Programmierer Fehler in meiner Programmiersprache? Leider nullist in einigen Sprachen häufig der Standardwert für nicht initialisierte (oder nicht explizit initialisierte) Zeiger oder Referenzen. Ist nullein Wert als Standardwert akzeptabel? Ist es als Standardwert sicher ? Manchmal nulldeutet dies auf freigegebene Werte hin. Sollte ich Verbrauchern meiner Schnittstelle einen Hinweis auf diese potenziellen Speicherverwaltungs- oder Initialisierungsprobleme in ihrem Programm geben? Was ist der Fehlermodus eines solchen Anrufs angesichts solcher Probleme? Befindet sich der Aufrufer im selben Prozess oder Thread wie ich, sodass solche Fehler ein hohes Risiko für meine Anwendung darstellen?

Abhängig von Ihren Antworten auf diese Fragen werden Sie wahrscheinlich feststellen können, ob dies nullfür Ihre Benutzeroberfläche geeignet ist oder nicht .

Beispiel 1

  1. Ihre Anwendung ist sicherheitskritisch
  2. Sie verwenden beim Start nulleine Art von Heap-Initialisierung. Dies ist ein möglicher Zeichenfolgenwert, der zurückgegeben wird, wenn für eine Zeichenfolge kein Speicherplatz zugewiesen wird.
  3. Möglicherweise trifft eine solche Zeichenfolge auf Ihre Benutzeroberfläche

Antwort: nullist wahrscheinlich nicht angebracht

Begründung: nullIn diesem Fall werden tatsächlich zwei verschiedene Arten von Werten angegeben. Der erste kann ein Standardwert sein, den der Benutzer Ihrer Schnittstelle festlegen möchte. Leider ist der zweite Wert ein Flag, das anzeigt, dass Ihr System nicht richtig funktioniert. In solchen Fällen möchten Sie wahrscheinlich so sicher wie möglich ausfallen (was auch immer das für Ihr System bedeutet).

Beispiel 2

  1. Sie verwenden eine C-Struktur, die ein char *Mitglied hat.
  2. Ihr System verwendet keine Heap-Zuordnung und Sie verwenden die MISRA-Prüfung.
  3. Ihre Schnittstelle akzeptiert diese Struktur als Zeiger und prüft, ob diese Struktur nicht auf zeigt NULL
  4. Der Standard- und sichere Wert des char *Mitglieds für Ihre API kann durch einen einzelnen Wert von angegeben werdenNULL
  5. Bei der Strukturinitialisierung Ihres Benutzers möchten Sie dem Benutzer die Möglichkeit geben, das char *Mitglied nicht explizit zu initialisieren .

Antwort: NULLkann angebracht sein

Begründung: Es besteht eine geringe Wahrscheinlichkeit, dass Ihre Struktur die NULLPrüfung besteht, jedoch nicht initialisiert ist. Ihre API ist jedoch möglicherweise nicht in der Lage, dies zu berücksichtigen, es sei denn, Sie haben eine Art Prüfsumme für den Strukturwert und / oder die Bereichsprüfung der Adresse der Struktur. MISRA-C-Linters können Benutzern Ihrer API helfen, indem sie die Verwendung von Strukturen vor ihrer Initialisierung kennzeichnen. Wie jedoch für das char *Element, wenn der Zeiger auf einem initialisierten struct auf struct, NULList der Standardwert von einer nicht spezifizierten Elements in einer struct Initialisierer. Daher NULLkann als sicher, Standardwert für das dient char *struct Mitglied in Ihrer Anwendung.

Wenn es sich um eine Serialisierungsschnittstelle handelt, stelle ich mir die folgenden Fragen, ob Null für eine Zeichenfolge verwendet werden soll.

  1. Gibt es nullHinweise auf einen potenziellen clientseitigen Fehler? Für JSON in JavaScript ist dies wahrscheinlich ein Nein, da dies nullnicht unbedingt als Hinweis auf einen Zuweisungsfehler verwendet wird. In JavaScript wird es als expliziter Hinweis auf das Fehlen von Objekten in einer Referenz verwendet, die problematisch festgelegt werden soll. Es gibt jedoch Parser und Serializer ohne Javascript, die JSON nulldem nativen nullTyp zuordnen. In diesem Fall wird diskutiert, ob die native nullVerwendung für Ihre spezielle Kombination aus Sprache, Parser und Serializer in Ordnung ist.
  2. Beeinflusst das explizite Fehlen eines Eigenschaftswerts mehr als einen einzelnen Eigenschaftswert? Manchmal zeigt a nulltatsächlich an, dass Sie einen neuen Nachrichtentyp haben. Es kann für Ihre Benutzer des Serialisierungsformats einfacher sein, nur einen völlig anderen Nachrichtentyp anzugeben. Auf diese Weise wird sichergestellt, dass ihre Validierungs- und Anwendungslogik eine klare Trennung zwischen den beiden Unterscheidungen von Nachrichten aufweist, die Ihre Webschnittstelle bereitstellt.

Allgemeine Hinweise

nullkann kein Wert an einer Kante oder Schnittstelle sein, der dies nicht unterstützt. Wenn Sie beim Eingeben von Eigenschaftswerten (z. B. JSON) etwas sehr Loses verwenden, versuchen Sie, eine Form von Schema oder Validierung auf der Consumer-Edgesoftware (z. B. JSON-Schema ) zu übertragen, sofern dies möglich ist. Wenn es sich um eine Programmiersprachen-API handelt, überprüfen Sie die Benutzereingaben nach Möglichkeit statisch (durch Eingabe) oder so laut, wie es zur Laufzeit sinnvoll ist (auch bekannt als defensives Programmieren auf Benutzeroberflächen). Wie wichtig, dokumentieren oder definieren Sie die Kante, damit folgende Fragen ausgeschlossen sind:

  • Welche Art von Wert eine bestimmte Eigenschaft akzeptiert
  • Welche Wertebereiche gelten für eine bestimmte Eigenschaft?
  • Wie ein Aggregattyp aufgebaut sein soll. Welche Eigenschaften müssen / sollten / können in einem Aggregattyp vorhanden sein?
  • Wenn es sich um einen Containertyp handelt, wie viele Elemente kann oder sollte der Container enthalten, und welche Arten von Werten enthält der Container?
  • In welcher Reihenfolge werden Eigenschaften oder Instanzen eines Container- oder Aggregattyps zurückgegeben?
  • Welche Nebenwirkungen hat das Setzen bestimmter Werte und welche Nebenwirkungen hat das Lesen dieser Werte?
zurückgestreut
quelle
1

Hier meine persönliche Analyse dieser Fragen. Es wird von keinem Buch, Papier, Studium oder was auch immer gestützt, nur von meiner persönlichen Erfahrung.

Leere Zeichenfolgen als null

Dies ist ein No-Go für mich. Mischen Sie nicht die Semantik eines leeren Strings mit der eines nicht definierten. In vielen Fällen können sie perfekt austauschbar sein, aber Sie können auch auf Fälle stoßen, in denen nicht definierte und definierte, aber leere Elemente etwas anderes bedeuten.

Eine Art dummes Beispiel: Nehmen wir an, es gibt ein Attribut, das einen Fremdschlüssel speichert, und dieses Attribut ist nicht definiert oder nullbedeutet, dass keine Beziehung definiert ist, wohingegen eine leere Zeichenfolge ""als definierte Beziehung verstanden werden könnte ID des Fremddatensatzes ist die leere Zeichenfolge.

Nicht definiert vs null

Dies ist kein schwarzes oder weißes Thema. Beide Ansätze haben Vor- und Nachteile.

Für die explizite Definition von nullWerten gibt es folgende Vorteile:

  • Die Nachrichten sind insofern selbsterklärender, als Sie alle Schlüssel kennenlernen, indem Sie sich eine Nachricht ansehen
  • In Bezug auf den vorherigen Punkt ist es einfacher, Fehler im Konsumenten der Daten zu codieren und zu erkennen: Es ist einfacher, Fehler zu erkennen, wenn Sie die falschen Schlüssel abrufen (möglicherweise Rechtschreibfehler, möglicherweise geänderte API usw.).

Für die Annahme eines nicht existierenden Schlüssels gilt die Semantik von null:

  • Einige Änderungen sind leichter zu bewältigen. Wenn beispielsweise eine neue Version des Nachrichtenschemas einen neuen Schlüssel enthält, können Sie den Konsumenten der Informationen so codieren, dass er mit diesem zukünftigen Schlüssel arbeitet, auch wenn der Produzent der Nachricht noch nicht aktualisiert wurde und diese Informationen noch nicht bereitstellt.
  • Nachrichten können weniger ausführlich oder kürzer sein

Für den Fall, dass die API irgendwie stabil ist und Sie sie gründlich dokumentieren, ist es meines Erachtens in Ordnung, anzugeben, dass ein nicht vorhandener Schlüssel der Bedeutung von entspricht null. Aber wenn es chaotischer und chaotischer ist (wie es ziemlich oft der Fall ist), können Sie Kopfschmerzen vermeiden, wenn Sie jeden Wert in jeder Nachricht explizit definieren. Dh im Zweifelsfall neige ich dazu, dem wortreichen Ansatz zu folgen.

Alles, was gesagt wurde, das Wichtigste: Erklären Sie Ihre Absichten klar und konsequent. Tu hier nicht das eine und dort nicht das andere. Vorhersehbare Software ist bessere Software.

bgusach
quelle
Das Beispiel für die Verwendung leerer Zeichenfolgen ist das, was ich unter Implementierungsdetails verstehe, dh unter der Annahme, dass die API zum Offenlegen von Datenbankzeilen verwendet wird. Wird es einen Unterschied machen, wenn keine Datenbank beteiligt ist und nur zur Übertragung von Objektdarstellungen dient?
imel96
Es muss kein Implementierungsdetail sein. In meinem Beispiel geht es eigentlich um PKs, die sich auf die Datenbank beziehen, aber ich habe versucht zu erklären, dass ein leerer String nicht nil / nothing / ist null. Ein weiteres Beispiel: In einem Spiel gibt es ein Charakterobjekt mit einem "Partner" -Attribut. Ein nullPartner bedeutet eindeutig, dass es überhaupt keinen Partner gibt, ""kann aber als Partner verstanden werden, dessen Name lautet "".
BGUSACH
Ich bin mit null Partner in Ordnung Referenzmittel gibt es keinen Partner und auch Referenz ist kein String. Aber der Name des Partners ist eine Zeichenfolge, selbst wenn Sie null als Partnernamen zulassen, würden Sie diese Null nicht abfangen und sie irgendwann durch eine leere Zeichenfolge ersetzen?
imel96
Wenn es keinen Partner gibt, würde ich die nullfür eine leere Zeichenfolge nicht ändern . Vielleicht wird es in einer Form gerendert, aber niemals im Datenmodell.
BGUSACH
Ich meinte nicht, kein Partner, Partner wäre ein Objekt. Es ist der Partner name, über den ich gesprochen habe. Würden Sie zulassen, dass der Name des Partners null ist?
imel96
1

In einer Situation, in der eine Zeichenfolge vorhanden ist und es sich zufällig um eine leere Zeichenfolge handelt, würde ich eine leere Zeichenfolge angeben. In einer Situation, in der ich ausdrücklich "Nein, diese Daten sind nicht vorhanden" sagen möchte, würde ich null angeben. Und lassen Sie den Schlüssel weg, um zu sagen "Keine Daten, keine Mühe".

Sie beurteilen, welche dieser Situationen eintreten können. Ist es für Ihre Anwendung sinnvoll, leere Zeichenfolgen zu haben? Möchten Sie zwischen der expliziten Angabe "Keine Daten" durch die Verwendung von Null und der impliziten Angabe ohne Wert unterscheiden? Sie sollten beide Möglichkeiten (null und kein Schlüssel vorhanden) nur haben, wenn beide vom Client unterschieden werden müssen.

Denken Sie jetzt daran, dass es nur um die Übertragung von Daten geht. Was der Empfänger mit den Daten macht, ist sein Geschäft, und er wird das tun, was für ihn am bequemsten ist. Der Empfänger sollte in der Lage sein, alles zu handhaben, was Sie darauf werfen (möglicherweise durch Zurückweisen der Daten), ohne abstürzen zu müssen.

Wenn es keine anderen Überlegungen gibt, würde ich übermitteln, was für den Absender am bequemsten ist, und es dokumentieren . Ich würde es vorziehen, überhaupt keine fehlenden Werte zu senden, da dies wahrscheinlich die Geschwindigkeit beim Codieren, Übertragen und Parsen von JSON verbessert.

gnasher729
quelle
Ich mag Ihren Punkt in "wenn vom Kunden unterschieden werden müssen".
imel96
0

Obwohl ich nicht sagen kann, was das Beste ist, handelt es sich mit ziemlicher Sicherheit nicht um ein einfaches Implementierungsdetail , sondern um eine Änderung der Struktur, wie Sie mit dieser Variablen interagieren können.

Wenn etwas null sein kann, sollten Sie es immer so behandeln, als ob es irgendwann null sein wird , sodass Sie immer zwei Workflows haben , einen für null, einen für eine gültige Zeichenfolge. Ein geteilter Workflow ist nicht unbedingt eine schlechte Sache, da es eine Menge Fehlerbehandlung und Spezialfälle gibt, die Sie verwenden könnten, aber Ihren Code verschleiern.

Wenn Sie immer auf die gleiche Weise mit der Zeichenfolge interagieren, ist es wahrscheinlich einfacher, die Funktionalität in Ihrem Kopf zu behalten .

Wie bei jeder "Was ist das Beste" -Frage bleibt mir die Antwort: Es kommt darauf an . Wenn Sie Ihren Workflow aufteilen und expliziter erfassen möchten, wenn etwas nicht festgelegt ist, verwenden Sie null. Wenn Sie möchten, dass das Programm einfach so weiterarbeitet, verwenden Sie eine leere Zeichenfolge. Wichtig ist, dass Sie konsequent sind , eine gemeinsame Rendite erzielen und dabei bleiben.

Angesichts der Tatsache, dass Sie eine API erstellen, würde ich empfehlen , an einer leeren Zeichenfolge festzuhalten, da der Benutzer weniger zu kompensieren hat, da ich als Benutzer einer API nicht alle Gründe kenne, aus denen Ihre API mir einen Nullwert geben könnte, es sei denn, Sie Es ist sehr gut dokumentiert, was einige Benutzer sowieso nicht lesen werden.

Erdrik Ironrose
quelle
Ein "geteilter Workflow" ist schlecht. Nehmen wir an, auf der Herstellerseite ist alles sauber, String-Typ-Methoden geben nur strings zurück, niemals null. Wenn die API null verwendet, muss der Produzent diese irgendwann erstellen null, um mit der API übereinzustimmen. Dann muss der Verbraucher auch damit umgehen null. Aber ich glaube, ich habe verstanden, was Sie sagen. Entscheiden Sie einfach und definieren Sie die API mit Autorität, oder? Bedeutet das, dass an keinem etwas auszusetzen ist?
imel96
Ja, was auch immer Sie in Ihrer API tun, wirkt sich darauf aus, wie der Benutzer seinen Code strukturieren muss. Wenn Sie also Ihr Design in Bezug auf den Benutzer der API berücksichtigen, sollten Sie in der Lage sein, den besten Weg zu definieren. Letztendlich ist es Ihre API. Sei einfach konsequent. Nur Sie können die Vor- und Nachteile für den Ansatz entscheiden.
Erdrik Ironrose
0

Dokumentieren!

TL; DR>

Tun Sie, was Sie für richtig halten - manchmal ist der Kontext entscheidend, in dem es verwendet wird. Beispiel: Variablen an Oracle SQL binden: Leere Zeichenfolge wird als NULL interpretiert.

Einfach würde ich sagen - Stellen Sie sicher, dass Sie jedes erwähnte Szenario dokumentieren

  • NULL
  • Leer (leer)
  • Fehlt (entfernt)

Ihr Code kann auf unterschiedliche Weise darauf reagieren - dokumentieren Sie, wie Ihr Code darauf reagiert:

  • Fehler (Ausnahme usw.), möglicherweise fehlgeschlagene Validierung (möglicherweise eine aktivierte Ausnahme) vs kann die Situation nicht korrekt behandeln (NullPointerException).
  • Geben Sie angemessene Standardeinstellungen an
  • Code verhält sich anders

Darüber hinaus liegt es an Ihnen, sich konsequent zu verhalten und möglicherweise einige Ihrer eigenen Best Practices zu übernehmen. Dokumentieren Sie dieses konsistente Verhalten. Beispiele:

  • Behandle Null und Missing gleich
  • Behandle eine leere Zeichenkette genauso. Nur im Fall einer SQL-Bindung kann dies als Leerzeichen betrachtet werden. Stellen Sie sicher, dass sich Ihre SQL konsistent und erwartungsgemäß verhält.
YoYo
quelle
Das Problem ist, dass, ohne auf die Bedenken einzugehen, Uneinigkeit ziemlich oft vorkam. In einer Teamumgebung muss die Entscheidung eine Teamentscheidung sein. Oft bedeutet dies, dass es einen Streit geben würde. Wenn Sie mehrere Teams haben, hat jedes Team das Recht, seine eigenen Entscheidungen zu treffen. Ich habe APIs gesehen, von denen ich nur vermuten kann, dass sie von verschiedenen Teams implementiert wurden, die nicht miteinander übereinstimmen. Wenn jemand einer Sache zustimmen kann, ist es trivial, sie zu dokumentieren.
imel96
0

tl; dr - wenn Sie es verwenden: Seien Sie konsequent in dem, was es bedeutet.

Wenn Sie einschließen null, was würde es bedeuten? Es gibt ein Universum von Dingen, was es bedeuten könnte. Ein Wert ist einfach nicht genug, um einen fehlenden oder unbekannten Wert darzustellen (und dies sind nur zwei der unzähligen Möglichkeiten: zB Fehlend - es wurde gemessen, aber wir wissen es noch nicht. Unbekannt - wir haben nicht versucht zu messen es.)

In einem Beispiel, auf das ich kürzlich gestoßen bin, könnte ein Feld leer sein, da es nicht zum Schutz der Privatsphäre einer Person gemeldet wurde. Es war jedoch auf der Seite des Absenders bekannt, nicht auf der Seite des Absenders, aber dem ursprünglichen Reporter bekannt oder beiden unbekannt. Und all dies war für den Empfänger von Bedeutung. Ein Wert reicht also in der Regel nicht aus.

Bei einer Annahme einer offenen Welt (Sie wissen einfach nichts über Dinge, die nicht angegeben sind) würden Sie es einfach weglassen und es könnte alles sein. Mit der Annahme einer geschlossenen Welt (Dinge, die nicht angegeben sind, sind beispielsweise in SQL falsch) sollten Sie klarstellen, was nullbedeutet, und mit dieser Definition so konsistent sein, wie Sie können ...

Grimaldi
quelle