Defensive, zukunftssichere Programmierung

Im Skype-Gespräch vor einigen Tagen hat SilverFalcon angemerkt, dass der Output der Methode user.getReadme() stets mit „°°°bi°“ endet. Die Ideen von djchrisnet und ihm, dieses Problem zu umschiffen waren zwar auf den ersten Blick zielführend, jedoch mittelfristig nicht gut. Ich verrate euch warum.

 

SilverFalcon hatte vorgeschlagen, bei der Readme die letzten 6 Zeichen abzuschneiden, um das Problem zu lösen:

var readme = user.getReadme().substr(0, (user.getReadme().length - 6))

Eigentlich hätte das ja bereits das Problem gelöst, aber er wusste nicht, dass ich bereits daran arbeitete, die Reset-Sequenz „°°°bi°“ aus dem Readme-Output der Methode zu entfernen. Hätte er nun also hart sechs Zeichen entfernt, so hätte er künftig nicht die ganze Readme genutzt oder im schlimmsten Fall sogar einen Crash im Code, sofern die Readme des Nutzers kürzer als sechs Zeichen wäre.

 

djchrisnet hat daraufhin eine andere Variante vorgeschlagen:

var readme = (user.getReadme().endsWith('°°°bi°')) ? user.getReadme().substr(0, (user.getReadme().length - 6)) : user.getReadme();

Abgesehen davon, dass die Zeile unleserlich lang ist, wird hier vielfach die Methode getReadme aufgrufen und die Verbindung der Zahl 6 zur Länge der Reset-Sequenz ist auch nur indirekt klar.

 

So haben wir das Problem intern gelöst:

const README_RESET_ENDING = '°°°bi°';
function getReadme()
{
    var readme = user.getReadme();

    if (readme.endsWith(README_RESET_ENDING))
    {
        return readme.substring(0, readme.length - README_RESET_ENDING.length);
    }

    return readme;
}

Warum ich das besser finde?

  • Es werden keine Magic-Numbers im Code benutzt. Die Zahl 6 steckt implizit in der README_RESET_ENDING.length. Sollte sich dieser String einmal verändern, so funktioniert der Code weiterhin
  • Der Code, der die Readme lädt wird nur ein einziges Mal aufgerufen und nicht mehrfach
  • Der Code ist übersichtlicher. Es ist leicht zu verstehen, was passiert. Zum einen, weil die Reset-Sequenz einen sprechenden Namen erhalten hat und zum anderen, weil der Code auf mehrere Zeilen aufgeteilt ist

 

6 Gedanken zu “Defensive, zukunftssichere Programmierung

  1. Wie sieht es im allgemeinen mit einer globalen Sammlung an standard kcode tokens aus? Ist ja nicht der einzige Fall wo man bezug drauf nimmt.

    Also einfach sowas wie
    App.KCode.RESET_FONT.length

    Oder App.KCode().RESET_FONT.length wenn man das KCode Objekt nur bei Bedarf instanzieren will.

    Like

    1. Hallo Ironist,

      wie sieht es aus, wenn der User Explizit „°°°bi°“ in seiner Readme hat? Warum auch immer er es sollte…. Jedenfalls ist im Ergebnis dann 2x °°°bi° vorhanden, es wird also nichts entfernt.

      Wäre es so nicht kürzer/besser:

      function getReadme()
      {
      const README_RESET_ENDING = „°°°bi°“;

      while (readme.IndexOf(README_RESET_ENDING) != -1)
      readme = readme.replace(README_RESET_ENDING, „“);

      return readme;
      }

      ?

      Somit würde jedes Vorkommen entfernt werden. Oder alternativ als if-Abfrage, dann könnte der User immerhin durch zweimaliger Eingabe von „°°°bi°“ noch ein einzelnes erhalten. Was wohl aber nie vorkommen wird.

      Ich habe das in c getestet, da ich mit der JavaScript-Syntax noch nicht so sehr gut klarkomme. ann ja sein, dass sich das ganze dort anders verhält, was ich aber nicht denke.

      MfG.

      Like

      1. Ahoi,

        dann ist trotzdem alles in Ordnung, denn es soll ja nur abgeschnitten werden, wenn es vom Server vorher angehangen wurde. Wenn ein Nutzer dies an seine Readme anfügt, dann möchte der Entwickler dies ja auch wissen.

        Knuddelige Grüße
        Ironist

        Like

  2. Moin,

    wenn der Server dies aber zusätzlich anhängt, wenn der User bereits diese Endung unwahrscheinlicherweise explizit mit in seiner Readme angegeben hat, also diese Konstante zwei mal am Ende ist, wird keines davon entfernt.

    Wenn ich an deine Funktion den Text: „DiesIsteineReadme°°°bi°°°°bi°“ übergebe, so ist der Resultstring wieder „DiesIsteineReadme°°°bi°°°°bi°“. In allen anderen Fällen funktioniert es wie gewünscht.

    Aber vielleicht ist das auch zu weit gedacht, da wie gesagt kaum ein User sowas bewusst in seiner Readme eingeben wird.

    Danke für deine Antwort.

    MfG Recaro.

    Like

  3. Ich stimme dir bei den ersten beiden Punkten zu. Beim dritten Punkt widerspreche ich dir. Es ist nicht leicht verständlich, was der Code macht. Ein Beweis dafür ist, dass er einen Fehler enthält: Bei Readmes mit fünf Zeichen schlägt er nämlich fehl, indem er einen Leerstring zurückgibt.
    Des Weiteren finde ich den Scope von README_RESET_ENDING unnötig groß.

    Ich würde den Code so schreiben:

    function getReadme() {
    const ENDING = ‚°°°bi°‘, readme = user.getReadme();
    return readme.endsWith(ENDING)
    ? readme.substr(0, readme.length – ENDING.length)
    : readme;
    }

    Wobei mir nicht klar ist, woher „user“ kommt. Eventuell wäre es besser, die Funktion zustandsfrei zu machen, indem man ihn als Paremeter übergibt. Als Vorteil hat man dann einfache Testbarkeit.

    Like

Hinterlasse einen Kommentar