Defensive Programming: Eingaben nicht auf Gültigkeit überprüfen!

  • Ersteller Ersteller ljr9i-_DlIE_ZzLKzKUWE5DX
  • Erstellt am Erstellt am
Status
Für weitere Antworten geschlossen.
L

ljr9i-_DlIE_ZzLKzKUWE5DX

Unregistriert
Du kontrollierst Eingangsparameter in deinen Methoden auf ihre Gültigkeit? Ich nicht. Auch ich habe das früher gemacht, aber jetzt nicht mehr. Ich lasse meine Methoden aber auch nicht einfach durch einen Null - Pointer oder andere Ausnahmen abstürzen. Das mag unlogisch klingen, aber nur am Anfang. Ich schlage vor wir verwenden Validierung Dekorateure.

Schauen wir uns dieses eher typisches Java-Beispiel an:

Code:
class Report {
  void export(File file) {
    if (file == null) {
      throw new IllegalArgumentException( "File is NULL; can't export." );
    }
    if (file.exists()) {
      throw new IllegalArgumentException( "File already exists." );
    }
    // Export the report to the file
  }
}
Ziemlich abwährend nicht wahr? Wenn wir nun diese Validierungen entfernen, wird der Code wesentlich kürzer, aber das Programm wird mit ziemlich verwirrenden Nachrichten abstürzen, wenn NULL vom Client als Eingabeparameter bereit gestellt wird. Darüber hinaus wird die Datei (in der export(File file) Methode erstellt) still überschrieben. Ziemlich gefährlich nicht wahr?

Wir müssen uns schützen und defensiv sein.

Aber nicht auf diese Weise, welche nichts mit der Kernfunktion der Klasse zutun habt. Stattdessen sollten wir Dekorateure verwenden, um die Validierung zu vollführen. Und so geht es. Als erstes brauchen wir eine Schnittstelle zum Report:
Code:
interface Report {
  void export(File file);
}
Danach brauchen wir eine Klasse, die Report in seiner Kernfunktionalität implementiert:

Code:
class DefaultReport implements Report { 

  @Override void export(File file) {
    // Export the report to the file
  }
}
Und letztlich eine Anzahl an Dekorateuren, die uns schützen werden:

Code:
class NoWriteOverReport implements Report {
  private final Report origin;

  NoWriteOverReport(Report rep) {
    this.origin = rep;
  }

  @Override void export(File file) {
    if (file.exists()) {
      throw new IllegalArgumentException( "File already exists." );
    }
    this.origin.export(file);
  }
}
Nun hat der Benutzer die Flexibilität ein komplexes Objekt aus Dekorateuren zu komponieren, die ihre spezifischen Aufgaben erledigen. Das Kern - Object wird nun die Berichterstattung übernehmen, während die Dekorateure die Parameter validieren werden:
Code:
Report report = new NoNullReport( new NoWriteOverReport( new DefaultReport() ) );
report.export(file);
Was haben wir nun mit diesem Ansatz erreicht? In erster Linie: kleinere Objekte. Und kleinere Objekte bedeuten immer höhere Wartbarkeit. Unsere DefaultReport Klasse wird immer klein bleiben, egal wie viele Validierungen wir in der Zukunft erfinden könnten. Je mehr Dinge, die wir validieren müssen, erschaffen, desto mehr Validierungs Dekorateure werden wir erschaffen. Alle von ihnen werden klein sein und Zusammenhang liefern. Neben dem werden wir ebenfalls in der Lage sein verschiedene Variationen zu setzen.

Abgesehen davon macht dieser Ansatz unseren Code viel mehr wiederverwendbar, da Klassen nur sehr wenig Operationen ausführen und nicht selbst Standardmäßig verteidigen. Während defensiv ein wichtiges Merkmal ist, werden wir die Validierungs Dekorateure benutzen. Aber dies wird nicht immer der Fall sein. Manchmal ist die Validierung einfach zu expressiv in Bezug auf Zeit und Memory und wir können direkt mit Objekten arbeiten, die sie nicht verteidigen.

Ich hoffe euch hat dieser Artikel gefallen und ihr konntet einiges an Wissen aus diesem Thread entnehmen. Ebenfalls würde mich interessieren, was die Developer und Ex Developer (wie @Overload , @geNAZt und @jasaush ) von meiner Meinung halten.

Liebe Grüße,
Justin | Koloso
 
Zuletzt bearbeitet von einem Moderator:
  • Like
Reaktionen: Steinstufe und 125ccm
Das einzige Problem was ich damit habe ist die Constructor Chain die ewig lang sein kann. Ebenso ist der Memory Footprint höher. Ich würde in diesem Falle eher Validation APIs (Commons oder Guava) nutzen um den Codestyle schön zu halten.
 
  • Like
Reaktionen: Steinstufe und 125ccm
Das einzige Problem was ich damit habe ist die Constructor Chain die ewig lang sein kann. Ebenso ist der Memory Footprint höher. Ich würde in diesem Falle eher Validation APIs (Commons oder Guava) nutzen um den Codestyle schön zu halten.
Klar ist das mit dem ewig lagen Konstruktor Chain ist richtig, aber Orcale hat doch genau für diesen Fall des erhöhten Memory Footprints auch noch extra Tunings vorgesehen. Die Validation API hat meiner Meinung nach das Problem, dass sie durch deren Annoations weniger Zusammenhalt haben, das wäre in diesem Fall glaube ich aber auch nicht so wild..

Aber danke für deine Meinung :)
 
Zuletzt bearbeitet von einem Moderator:
Klar ist das mit dem ewig lagen Konstruktor Chain ist richtig, aber Orcale hat doch genau für diesen Fall des erhöhten Memory Footprints auch noch extra Tunings vorgesehen. Die Validation API hat meiner Meinung nach das Problem, dass sie durch deren Annoations weniger Zusammenhalt haben, das wäre in diesem Fall glaube ich aber auch nicht so wild..

Aber danke für deine Meinung :)
Ich würde dir auch die GuavaAPI empfehlen ;D
 
Status
Für weitere Antworten geschlossen.

Soziale Medien

  • X
  • TikTok

Über uns

  • GommeHD.net ist einer der größten Minecraft-Server der Welt. Dir gefällt unser Server? Dann unterstütze uns durch einen Kauf im Shop!
  • Shop