Verträge Die praktische Seite der Semantik

Wir alle wissen, dass wir semantischen Code schreiben sollten. Vielleicht benutzt du sogar

oder richtig und fühle mich ziemlich gut mit dir. Berücksichtigen Sie auch den implizierten Vertrag, den Sie beim Codieren haben?

Stellen wir uns vor, dass ein Kunde einen Textlink anfordert. “Mehr sehen,”, Der zusätzlichen Text auf der Seite anzeigen soll. Mehr sehen mit einem click-handler sollte einwandfrei funktionieren, oder? Hey, es sieht aus und funktioniert wie gewünscht!

Nein, es funktioniert nicht immer korrekt, da es den Vertrag zwischen Ihnen und dem Browser verletzt. Ich beziehe mich insbesondere auf den, der das sagt href Das Attribut muss einen Wert haben, der eine gültige URL ist.

Es gibt praktische Probleme, die bei Vertragsverletzungen auftreten können. Dies sind viel bessere Gründe, semantischen Code zu schreiben, als Dinge, an die Sie normalerweise denken, wenn Sie den Begriff „semantisch“ hören..


Beliebte Argumente für semantischen Code

Es gibt jedoch viel mehr praktische Gründe, sich für Semantik zu interessieren: Verträge.

Wenn Sie einen durchschnittlichen Entwickler nach dem Wert des semantischen Codes fragen, hören Sie wahrscheinlich etwas in der Art von:

  • Es hilft den Behinderten
  • Die korrekte Beschreibung des Codes erleichtert die Interpretation von Maschinen

Beide sind leider sehr leicht zu vernachlässigen. "Blinde Menschen und Roboter sind nicht das Zielpublikum" ist eine zu einfache Antwort, unabhängig davon, wie falsch oder unwissend sie ist.

In anderen Fällen hören Sie vielleicht sogar eine zyklische Argumentation, z. B. „Nicht-semantischer Code ist schlecht, weil er nicht sinnvoll ist“. Es ist eine so verbreitete Vorstellung, dass bereits Parodien im Web auftauchen!

Es gibt jedoch viel mehr praktische Gründe, sich für Semantik zu interessieren: Verträge.


Nutzungsverträge

Jedes Mal, wenn Sie bestimmte Funktionen verwenden, die von Browseranbietern, Ihrer Programmiersprache oder einer API bereitgestellt werden, verlassen Sie sich auf einen Vertrag.

Auf einer Seite des Vertrages existiert ein Anbieter von Funktionalität. Zum Beispiel, wenn Sie eine Tag, Browser-Entwickler versprechen Ihnen, dass sie dem Benutzer Ihrer Anwendung eine einfache Möglichkeit bieten, zur angegebenen URL zu navigieren.

Wie immer gibt es jedoch die andere Seite dieses Vertrages. Der Implementierer der Funktionalität verspricht, die angegebene Funktionalität zu verwenden. Sobald er diese Funktion missbraucht, sind alle Wetten gesperrt - was zu einem Fehlschlag führen kann.

Browserfunktionsverträge

Kommen wir zum “Mehr sehenBeispiel aus früher. In den frühen Tagen von JavaScript haben Entwickler ihr JavaScript unter Verwendung eines Pseudo-Protokolls geschrieben, Javascript:

 Mehr sehen

Sie stellten relativ schnell fest, dass dieser Ansatz mindestens einen praktischen Fehler aufweist: Der JavaScript-Code wird in der Statusleiste des Browsers angezeigt, was nicht professionell aussieht. Die Antwort auf dieses Dilemma bestand darin, den Code in ein onclick Handler, und ersetzen Sie die href Attribut mit einem leeren Hash-Bezeichner wie folgt:

 Mehr sehen

Das hat natürlich nicht alles gelöst. Ob Zeig mehr hat einen Fehler, falsch zurückgeben wird nie aufgerufen und die Seite wird nach oben gescrollt - sicherlich kein gewünschtes Verhalten.

Heute trennen Entwickler HTML und JavaScript voneinander und verwenden geeignete Techniken zur Verhinderung von Ereignissen:

 Mehr sehen
 $ ('a.show-more'). on ('click', function (event) event.preventDefault (); ShowMore (););

Aber rate mal was? Bei diesem Ansatz gibt es noch viele Probleme: Das Öffnen in einem neuen Tab, das Hinzufügen von Lesezeichen oder das Kopieren des Links funktioniert nicht wie erwartet (insbesondere wenn ein Browser vorhanden ist) Tag auf der Seite), was zu Verwirrung und möglicherweise zu einem verlorenen Kunden führt.

Beachten Sie, dass alle bisher beschriebenen Probleme auf eine einzige Tatsache zurückzuführen sind. Entwickler haben ihren Vertragsteil mit den Browserherstellern verletzt: href Das Attribut muss eine korrekte URL enthalten, stattdessen haben die Entwickler alle Arten von Müll eingefügt.

Wenn wir versuchen, unseren Vertrag einzuhalten, müssen wir uns fragen: "Warum erlaubt uns der Vertrag nicht, das zu tun, was wir brauchen?" Die Antwort ist einfach: Wir missbrauchen das Etikett. Wir benutzen es nur, weil wir den Text wollen “Mehr sehen”Erscheinen und sich wie ein Link verhalten. Wenn wir jedoch Wörter wie "aussehen" und "erscheinen" verwenden, ist dies nicht die Domäne von CSS? Ist das nicht "Mehr sehen"Link, in Wirklichkeit nur eine Schaltfläche? Dies ist einfach zu implementieren:

 
 $ ('button.show-more'). on ('click', ShowMore);
 a, .link-style color: @ your-shade-of-blue; Textdekoration: Unterstrichen;  .link-style font: erben; Hintergrund: keine; Grenze: keine; Cursor: Zeiger; 

Unabhängig davon, wie viele neue Möglichkeiten der Interaktion mit Links zu zukünftigen Iterationen der Browser hinzugefügt werden, wird dieser Ansatz weiter funktionieren, da wir keinen Vertrag mit dem Browser verletzen. Wir verwenden Elemente, um ihre Bedeutung zu vermitteln, und anstatt ständig neue Probleme zu umgehen, wissen wir, dass der Browser dies richtig behandelt versteht was wir wollen.

Sicher, es sind möglicherweise ein paar zusätzliche CSS-Zeilen erforderlich, um einige der Standard-Schaltflächenstile zurückzusetzen. Das ist es wert! Sei nicht faul.

Spezifikationen als Verträge

… Diejenigen, die die Semantik kannten und sie wissentlich ignorierten.

Im Jahr 2005 lernte ein großer Teil der Webentwicklungsgemeinschaft, dass es schwierig ist, HTTP-Anforderungen zu ignorieren. Der neu veröffentlichte Google Web Accelerator gibt URLs auf einer Seite vor, um die Wartezeit des Benutzers auf einen Klick zu minimieren.

Dies zerstörte Verwüstungen in Anwendungen, die HTTP ignorierten und destruktive Operationen hinter einfachen Links hinterließen. Und es gab viele solcher Anwendungen.

Das Problem lag nicht in den Händen der Entwickler, die die Semantik von HTTP-Methoden nicht verstanden haben. Nein, das Problem kam von denen, die die Semantik kannten, wissentlich ignorierten und das Wissen nicht teilten.


Wartungsverträge

Verwirrender Code ist schlecht!

Verträge bestehen auch zwischen Entwicklern. Jedes Mal, wenn Sie eine Zeile Code schreiben, versprechen Sie zukünftigen Entwicklern, dass sie genau das tut, was sie zu tun scheint. Mit anderen Worten, verwirrender Code ist schlecht!

Verwenden Sie beispielsweise eine Filterfunktion (z. B. Filter In Python) ist das Überschreiben von Elementen nicht korrekt, da es einen implizierten Vertrag gibt, der besagt, dass Filterfunktionen nur die Liste ändern, ohne dass dabei Nebenwirkungen auftreten:

 def show (item): print (item) fruits = ['orange', 'apple', 'lemon'] filter (show, fruits) # Falsche Verwendung des Filters

Verwenden Sie stattdessen eine explizite Schleife für eine Liste:

 def show (item): print (item) Früchte = ['Orange', 'Apfel', 'Zitrone'] für Obst in Früchten: Show (Obst)

Wenn Sie sich hingegen auf einen Vertrag verlassen können, können Sie dadurch den Code klarer darstellen. Zum Beispiel mit array_filter anstelle einer zum Eine Schleife in PHP zum Filtern von Elementen ermöglicht es anderen Entwicklern, nach einem Blick zu verstehen, was passiert:

 $ Einkommen = [20, 15, -7, 19]; $ profit = array_filter ($ einkommen, Funktion ($ i) return $ i> 0;);

Vergleichen Sie den obigen Ausschnitt mit a zum Schleife:

 $ Einkommen = [20, 15, -7, 19]; $ Gewinne = []; foreach ($ Einkommen als $ i) if ($ i> 0) $ profit [] = $ i; 

Die zweite Version ist schlechter, nicht nur weil sie länger ist, sondern auch weil array_filter gibt eine Erwartung. Es ist klar, dass $ Gewinne ist eine Teilmenge von $ Einnahmen. Es gibt keine solche Konvention mit einem Generikum zum Schleife, was erklärt, warum wir keine Annahmen treffen können, ohne zuerst das Innere der Schleife zu entschlüsseln.


Richtig semantischer Code schreiben

Wie unterscheidet man Code, der semantisch ist und nicht? Wie bemerken Sie diese Verträge? Zum größten Teil genügt es, sich selbst Fragen zu stellen.

HTML-Tags

„Ich benutze eine tag und ich muss etwas in ein href Attribut. href speichert das Link-Zielziel. Woher kommt mein Tag-Link zu? “Nirgendwo? Nun, ich kann daraus schließen, dass ich diesen Tag wahrscheinlich missbrauchen kann.

Benannte Funktionen

„Ich muss den Inhalt meiner Liste in einer Liste ausdrucken Filter Funktion. Ist das Ausdrucken von Elementen Teil des Filtervorgangs? ”Nicht wirklich. Das heißt, ich missbrauche Filter.

Funktionen, die zu viel tun

„Ich schreibe ein getFoo Methode und müssen etwas Modifikationscode hinzufügen. Ist es sinnvoll, den Status zu ändern, um Foo zu bekommen? Würde jemand, der einfach nur Foo bekommen will, erwarten, dass etwas anderes passiert? “Wahrscheinlich nicht!

Trennung von Bedenken

„Ich möchte JavaScript in einem HTML-Code hinzufügen onclick Attribut. Ist das richtig? ”Die Datei, die Sie ändern, ist .html, Recht? Platzieren Sie stattdessen JavaScript und CSS .js und .css Dateien. Immer.

In vielen Fällen sind natürlich einige zusätzliche Kenntnisse erforderlich, um die Situation richtig einschätzen zu können. Am wichtigsten ist es, über diese Dinge nachzudenken und das Prinzip zu vermeiden.es (irgendwie) funktioniert, also ist es gut genug.Fragen Sie sich stattdessen immer: "Was bedeutet der Code, den ich schreibe?"


Fazit

Ein Verstoß gegen einen Vertrag stellt sicher, dass die Zusammenarbeit unterbrochen wird.

Die Zusammenarbeit hängt immer von den Bemühungen beider Seiten ab. Ein Großteil der Softwareentwicklung beschränkt sich auf die Zusammenarbeit: Zusammenarbeit zwischen Hardwareherstellern, Systemprogrammierern, Browserentwicklern, Bibliotheksautoren, Websiteentwicklern und vielen anderen. Ein Verstoß gegen einen Vertrag stellt sicher, dass die Zusammenarbeit unterbrochen wird.

Die Codesemantik ist ein solcher Vertrag. Kümmern Sie sich um Ihr Wohl!


Fußnoten

Semantisch: Der Begriff "semantisch" wird oft missverstanden. Im Zusammenhang mit diesem Artikel verwende ich den Begriff zur Unterscheidung von Bedeutung des Codes von dem Ergebnisse, die der Code erzeugt. Zum Beispiel semantische Bedeutung von Tag ist Darstellung eines Links, während die einfache, praktische Bedeutung davon ist anklickbarer, unterstrichener Text.

Streng genommen eine leere Fragmentkennung # könnte in diesem Zusammenhang als gültig betrachtet werden. Diese Technik versäumt jedoch den Punkt, den ich in dem Artikel anführe.