Dieser Artikel wurde von Deji Akala und Marco Pivetta überprüft. Vielen Dank an alle Peer -Rezensenten von SitePoint, um den besten Inhalt in SitePoint zu erhalten!
Das Verständnis der Code des anderen und der Verwendung kann manchmal schwierig werden, wenn mittlere und große Teams an derselben Codebasis zusammenarbeiten. Zu diesem Zweck gibt es mehrere Lösungen. Beispielsweise kann vereinbart werden, eine Reihe von Codierungsstandards zu befolgen, um die Lesbarkeit Ihres Codes zu verbessern oder ein Framework zu verwenden, das allen Teammitgliedern bekannt ist (der hervorragende Laravel-Einstiegskurs ist hier verfügbar).
Dies reicht jedoch normalerweise nicht aus, insbesondere wenn es notwendig ist, sich in den Anwendungsabschnitt zu befassen, der vor einiger Zeit geschrieben wurde, um Fehler zu beheben oder neue Funktionen hinzuzufügen. Zu diesem Zeitpunkt ist es schwierig, sich daran zu erinnern, wie von einer bestimmten Klasse erwartet wird, dass sie funktioniert, einschließlich sich selbst und wie sie miteinander kombiniert werden. An diesem Punkt ist es einfach, versehentlich Nebenwirkungen oder Fehler einzuführen, ohne sie zu kennen.
Diese Fehler können in der Qualitätssicherung gefunden werden, können aber auch wirklich ignoriert werden. Selbst wenn sie entdeckt werden, kann das Rücksenden des Code und die Behebung viel Zeit in Anspruch nehmen.
Wie verhindern wir das? Die Antwort lautet "poka yok" .
Poka Yoke ist ein japanischer Begriff, der ungefähr "Anti-Irrtum" übersetzt. Der Begriff stammt aus der mageren Herstellung und bezieht sich auf jeden Mechanismus, der dem Maschinenbetreiber Fehlern vermeidet.
Zusätzlich zur Herstellung wird Poka Yoke häufig in der Unterhaltungselektronik verwendet. Beispielsweise können SIM -Karten aufgrund ihrer asymmetrischen Form nur in eine Weise in die SIM -Tablett eingefügt werden.
Das Hardware -Beispiel ohne Poka -Joch ist der PS/2 -Port, der genau die gleiche Form für den Tastaturanschluss und den Mausanschluss hat. Sie können nur durch die Verwendung von Farbcodes unterschieden werden, sodass es einfach ist, die Anschlüsse versehentlich auszutauschen und in die falschen Ports einzulegen, da sie alle auf die gleiche Weise passen.
Zusätzlich zur Verwendung in Hardware kann das Konzept von Poka Yoke auch auf die Programmierung angewendet werden. Die Idee ist, die öffentliche Schnittstelle unseres Code so leicht wie möglich zu verstehen und sofort einen Fehler zu werfen, wenn der Code falsch verwendet wird. Dies scheint offensichtlich zu sein, aber wir begegnen oft Code, der in dieser Hinsicht Fehler aufweist.
Beachten Sie jedoch, dass Poka Yoke nicht dazu gedacht ist, einen vorsätzlichen Missbrauch zu verhindern. Sein Ziel ist es, unerwartete Fehler zu verhindern und den Code nicht vor böswilliger Verwendung zu schützen. Solange jemand Zugriff auf Ihren Code hat, können sie Ihre Sicherheitsmaßnahmen immer umgehen, wenn er es wirklich will.
Bevor Sie diskutieren, welche spezifischen Maßnahmen ergriffen werden können, um den Code fehlersicherer zu gestalten, ist es wichtig zu wissen, dass der Poka-Joch-Mechanismus normalerweise in zwei Kategorien unterteilt werden kann:
Fehlerpräventionstechniken helfen dabei, Fehler so früh wie möglich zu erkennen. Sie sollen sicherstellen, dass niemand unseren Code versehentlich falsch verwenden kann, indem die Schnittstelle und das Verhalten so einfach und unkompliziert wie möglich gestaltet werden. Denken Sie an das Beispiel einer SIM -Karte, die nur in eine Weise in das SIM -Tablett eingefügt werden kann.
Andererseits existiert der Fehlererkennungsmechanismus außerhalb unseres Code. Sie überwachen unsere Anwendungen für potenzielle Fehler und warnen uns. Ein Beispiel besteht darin, festzustellen, ob ein mit einem PS/2 -Port verbundener Gerät der richtige Softwaretyp ist, und wenn nicht, wird dem Benutzer eine Warnung angezeigt, warum es nicht funktioniert. Diese bestimmte Software kann Fehler nicht verhindern, da der Anschluss beim Einfügen austauschbar ist, aber Fehler erkennen und uns warnen kann, damit der Fehler behoben werden kann.
Im Rest dieses Artikels werden wir verschiedene Methoden untersuchen, die zur Implementierung der Fehlerprävention und der Fehlererkennung in unseren Anwendungen verwendet werden können. Aber denken Sie daran, dass diese Liste nur ein Ausgangspunkt ist. Abhängig von Ihrer spezifischen Anwendung können zusätzliche Maßnahmen vorliegen, die Ihren Code fehlerhafter machen können. Es ist auch wichtig, sich an die Vorabkosten von Poka Yoke zu erinnern und sicherzustellen, dass es sich für Ihr spezifisches Projekt lohnt. Abhängig von der Komplexität und Größe der Anwendung können einige Maßnahmen im Vergleich zu potenziellen Fehlerkosten zu teuer sein. Daher müssen Sie und Ihr Team entscheiden, welche Maßnahmen für Sie am besten sind.
Beispiel für Fehlerverhütung
Durch die Zuweisung eines bestimmten Typs zu den Funktionsparametern wird die Reihenfolge des Parameters beim Aufrufen einer Funktion schwieriger.
Schauen wir uns beispielsweise diese Benachrichtigung an, die wir vielleicht an den Benutzer senden möchten:
<?php class Notification { private $userId; private $subject; private $message; public function __construct( $userId, $subject, $message ) { $this->userId = $userId; $this->subject = $subject; $this->message = $message; } public function getUserId() { return $this->userId; } public function getSubject() { return $this->subject; } public function getMessage() { return $this->message; } }
Ohne eine Typdeklaration können wir leicht Variablen des falschen Typs injizieren, die unsere Anwendung brechen können. Zum Beispiel können wir davon ausgehen, dass $ userID eine Zeichenfolge sein sollte, und es muss möglicherweise eine Ganzzahl sein.
Wenn wir den falschen Typ injizieren, wird der Fehler möglicherweise erst erkannt, wenn die Anwendung versucht, die Benachrichtigung tatsächlich zu verarbeiten. Bis dahin könnten wir einige unverständliche Fehlermeldungen über unerwartete Typen erhalten, aber nichts weist sofort auf unseren Code hin, der Strings anstelle von Zahlen injiziert.
Daher ist es normalerweise interessanter, die Anwendung so bald wie möglich zum Absturz zu zwingen, damit solche Fehler während der Entwicklung so früh wie möglich erkannt werden können.
In diesem Fall können wir einfach eine Typ -Deklaration hinzufügen, und wenn wir den Parametertyp verschleiern, bleibt PHP sofort an und warnt uns vor einem tödlichen Fehler:
<?php declare(strict_types=1); class Notification { private $userId; private $subject; private $message; public function __construct( int $userId, string $subject, string $message ) { $this->userId = $userId; $this->subject = $subject; $this->message = $message; } public function getUserId() : int { return $this->userId; } public function getSubject() : string { return $this->subject; } public function getMessage() : string { return $this->message; } }
Beachten Sie jedoch, dass PHP standardmäßig versucht, falsche Parameter an ihren erwarteten Typ zu geben. Um dies zu verhindern, ist es wichtig, dass wir strict_types aktivieren, damit wir beim Auftreten eines Fehlers tatsächlich einen tödlichen Fehler erhalten. Daher sind Skalartyp -Deklarationen keine idealen Poka -Joch -Formen, aber sie sind ein guter Anfang, um Fehler zu reduzieren. Auch wenn strict_types deaktiviert sind, können sie dennoch als Hinweis auf den erwarteten Typ des Parameters dienen.
Zusätzlich deklarieren wir den Rückgabetyp für die Methode. Diese erleichtern es, zu bestimmen, welchen Wert Sie beim Aufrufen einer bestimmten Funktion erwarten können.
operativ definierte Rückgabetypen helfen auch dabei, eine große Anzahl von Switch -Anweisungen bei der Verarbeitung von Rückgabewerten zu vermeiden, da unsere Methode verschiedene Typen ohne explizit deklarierte Rückgabetypen zurückgeben kann. Diejenigen, die unsere Methode verwenden, müssen also überprüfen, welcher Typ tatsächlich in einem bestimmten Fall zurückgegeben wird. Diese Switch -Anweisungen werden offensichtlich vergessen und führen zu nicht nachweisbaren Fehlern. Bei Verwendung von Rückgabetypen werden solche Fehler stark reduziert.
Ein Problem, dass der Skalartyp Hinweise nicht leicht für uns gelöst werden kann, ist, dass mehrere Funktionsparameter es ermöglicht, die Reihenfolge dieser Parameter zu verwirren.
PHP kann uns warnen, wenn wir die Reihenfolge der Parameter verschleiern, wenn alle Parameter unterschiedliche Skalartypen haben, aber in den meisten Fällen haben wir möglicherweise einige Parameter mit demselben Typ.
Um dieses Problem zu lösen, können wir unsere Parameter wie folgt in ein Wertobjekt einwickeln:
class UserId { private $userId; public function __construct(int $userId) { $this->userId = $userId; } public function getValue() : int { return $this->userId; } } class Subject { private $subject; public function __construct(string $subject) { $this->subject = $subject; } public function getValue() : string { return $this->subject; } } class Message { private $message; public function __construct(string $message) { $this->message = $message; } public function getMessage() : string { return $this->message; } } class Notification { /* ... */ public function __construct( UserId $userId, Subject $subject, Message $message ) { $this->userId = $userId; $this->subject = $subject; $this->message = $message; } public function getUserId() : UserId { /* ... */ } public function getSubject() : Subject { /* ... */ } public function getMessage() : Message { /* ... */ } }
Da unsere Parameter jetzt einen ganz bestimmten Typ haben, ist es fast unmöglich, sie zu verwirren.
Ein weiterer Vorteil der Verwendung von Wertobjekten anstelle einer Skalartypdeklaration besteht darin, dass wir in jeder Datei nicht mehr strict_types aktivieren müssen. Wenn wir uns nicht daran erinnern müssen, können wir es nicht versehentlich vergessen.
Bei Verwendung von Wertobjekten können wir ihre Datenüberprüfungslogik im Objekt selbst zusammenfassen. Auf diese Weise können wir die Erstellung von Wertobjekten mit ungültigem Zustand verhindern, was zu Problemen in anderen Schichten der Anwendung führen kann.
Zum Beispiel könnten wir eine Regel haben, dass eine bestimmte Benutzer -ID immer positiv sein sollte.
Wir können diese Regel offensichtlich jedes Mal überprüfen, wenn wir BenutzerID als Eingabe erhalten, aber andererseits kann sie auch an der einen oder anderen Stelle leicht vergessen werden.
Auch wenn dieser Fehler in einer anderen Schicht der Anwendung einen tatsächlichen Fehler auftritt, gibt die Fehlermeldung möglicherweise nicht eindeutig an, welcher Fehler tatsächlich aufgetreten ist und ist schwer zu debuggen.
Um solche Fehler zu verhindern, können wir dem Benutzer -Konstruktor eine Validierung hinzufügen:
<?php class Notification { private $userId; private $subject; private $message; public function __construct( $userId, $subject, $message ) { $this->userId = $userId; $this->subject = $subject; $this->message = $message; } public function getUserId() { return $this->userId; } public function getSubject() { return $this->subject; } public function getMessage() { return $this->message; } }
Auf diese Weise können wir immer sicherstellen, dass es bei der Verwendung des Benutzer -ID -Objekts einen gültigen Status hat. Dies hindert uns daran, unsere Daten auf allen Ebenen unserer Anwendung ständig zu verehren.
Beachten Sie, dass wir Skalartyp -Deklarationen hinzufügen können, anstatt IS_int zu verwenden. Dies zwingt uns jedoch, strict_types überall zu ermöglichen, wo wir UserID verwenden.
Wenn wir strict_types nicht aktivieren, versucht PHP automatisch, andere Typen an int zu geben, wenn sie an userID weitergegeben werden. Dies kann problematisch sein, beispielsweise können wir eine schwimmende Punktzahl injizieren, die tatsächlich eine falsche Variable sein kann, da die Benutzer -ID keine schwimmende Punktzahl ist.
In anderen Fällen, z. B. wenn wir möglicherweise ein Preiswertobjekt verwenden, kann das Deaktivieren von strict_types zu einem Rundungsfehler führen, da PHP automatisch schwimmende Punktvariablen in Int umwandeln.
standardmäßig werden Objekte in PHP mit Referenz übergeben. Dies bedeutet, dass sich bei Änderungen am Objekt unmittelbar während der gesamten Anwendung ändert.
Während diese Methode ihre Vorteile hat, hat sie auch einige Nachteile. Schauen wir uns ein Beispiel für das Senden von Benachrichtigungen an Benutzer per Textnachrichten und E -Mails an:
<?php declare(strict_types=1); class Notification { private $userId; private $subject; private $message; public function __construct( int $userId, string $subject, string $message ) { $this->userId = $userId; $this->subject = $subject; $this->message = $message; } public function getUserId() : int { return $this->userId; } public function getSubject() : string { return $this->subject; } public function getMessage() : string { return $this->message; } }
Wir verursachen unerwartete Nebenwirkungen, da das Benachrichtigungsobjekt mit Referenz übergeben wird. Durch die Verkürzung der Länge der Nachricht in SMSNotificationsSender wird das referenzierte Benachrichtigungsobjekt in der gesamten Anwendung aktualisiert, sodass es auch verkürzt wird, wenn sie später von der E -Mail -Notifikation gesendet wird.
Um dieses Problem zu lösen, können wir unser Benachrichtigungsobjekt unveränderlich machen. Anstatt eine festgelegte Methode zur Änderung bereitzustellen, können wir einige Methoden hinzufügen, um eine Kopie der ursprünglichen Benachrichtigung zu erstellen und dann die Änderungen anzuwenden:
class UserId { private $userId; public function __construct(int $userId) { $this->userId = $userId; } public function getValue() : int { return $this->userId; } } class Subject { private $subject; public function __construct(string $subject) { $this->subject = $subject; } public function getValue() : string { return $this->subject; } } class Message { private $message; public function __construct(string $message) { $this->message = $message; } public function getMessage() : string { return $this->message; } } class Notification { /* ... */ public function __construct( UserId $userId, Subject $subject, Message $message ) { $this->userId = $userId; $this->subject = $subject; $this->message = $message; } public function getUserId() : UserId { /* ... */ } public function getSubject() : Subject { /* ... */ } public function getMessage() : Message { /* ... */ } }
Auf diese Weise, wenn wir die Benachrichtigungsklasse ändern, werden beispielsweise die Änderungen nicht mehr während der Anwendung ausbreitet, wodurch unerwartete Nebenwirkungen verhindert werden.
Aber beachten Sie, dass es schwierig ist (wenn nicht unmöglich), ein Objekt in PHP wirklich unveränderlich zu machen. Um unseren Code fehlerhafter zu gestalten, ist es bereits hilfreich, wenn wir mit Methoden anstelle von Methoden "unveränderlich" hinzufügen, da der Benutzer der Klasse nicht mehr daran denken muss, das Objekt selbst zu klonen, bevor sie Änderungen vornehmen.
Manchmal haben wir Funktionen oder Methoden, die bestimmte Werte oder Null zurückgeben können. Diese nullbaren Rückgabeteile können Probleme verursachen, da sie fast immer prüfen müssen, ob sie leer sind, bevor wir sie verwenden können. Auch dies können wir leicht vergessen. Um zu vermeiden, dass Sie den Rückgabewert immer überprüfen müssen, können wir stattdessen ein leeres Objekt zurückgeben.
Zum Beispiel könnten wir ein Einkaufsbetrieb haben, bei dem Rabatte angewendet werden oder keine Rabatte angewendet werden:
<?php class Notification { private $userId; private $subject; private $message; public function __construct( $userId, $subject, $message ) { $this->userId = $userId; $this->subject = $subject; $this->message = $message; } public function getUserId() { return $this->userId; } public function getSubject() { return $this->subject; } public function getMessage() { return $this->message; } }
Bei der Berechnung des Endpreises von ShoppingCart müssen wir jetzt immer überprüfen, ob GetDiscount () Null- oder tatsächliche Rabatt zurückgibt, bevor wir die Antragsmethode anrufen können:
<?php declare(strict_types=1); class Notification { private $userId; private $subject; private $message; public function __construct( int $userId, string $subject, string $message ) { $this->userId = $userId; $this->subject = $subject; $this->message = $message; } public function getUserId() : int { return $this->userId; } public function getSubject() : string { return $this->subject; } public function getMessage() : string { return $this->message; } }
Wenn wir diesen Scheck nicht durchführen, erhalten wir möglicherweise PHP -Warnungen und/oder andere unerwartete Effekte, wenn getDiscount () null zurückgibt.
Andererseits können wir diese Überprüfungen vollständig löschen:
, wenn wir ein leeres Objekt zurückgeben, wenn Rabatt nicht festgelegt ist:class UserId { private $userId; public function __construct(int $userId) { $this->userId = $userId; } public function getValue() : int { return $this->userId; } } class Subject { private $subject; public function __construct(string $subject) { $this->subject = $subject; } public function getValue() : string { return $this->subject; } } class Message { private $message; public function __construct(string $message) { $this->message = $message; } public function getMessage() : string { return $this->message; } } class Notification { /* ... */ public function __construct( UserId $userId, Subject $subject, Message $message ) { $this->userId = $userId; $this->subject = $subject; $this->message = $message; } public function getUserId() : UserId { /* ... */ } public function getSubject() : Subject { /* ... */ } public function getMessage() : Message { /* ... */ } }
Wenn wir nun getDiscount () anrufen, erhalten wir immer das Rabattobjekt, auch wenn kein Rabatt verfügbar ist. Auf diese Weise können wir den Rabatt auf unsere Gesamtsumme anwenden, und auch ohne Rabatt benötigen wir die IF -Erklärung nicht mehr:
class UserId { private $userId; public function __construct($userId) { if (!is_int($userId) || $userId <= 0) { throw new \InvalidArgumentException( 'UserId should be a positive integer.' ); } $this->userId = $userId; } public function getValue() : int { return $this->userId; } }
Aus Gründen, aus denen wir nullbare Rückgaberwerte vermeiden möchten, möchten wir möglicherweise optionale Abhängigkeiten vermeiden, aber nur alle unsere Abhängigkeiten notwendig machen.
Zum Beispiel die folgende Klasse:
interface NotificationSenderInterface { public function send(Notification $notification); } class SMSNotificationSender implements NotificationSenderInterface { public function send(Notification $notification) { $this->cutNotificationLength($notification); // 发送短信... } /** * 确保通知不超过短信长度。 */ private function cutNotificationLength(Notification $notification) { $message = $notification->getMessage(); $messageString = substr($message->getValue(), 0, 160); // 修正截取长度 $notification->setMessage(new Message($messageString)); } } class EmailNotificationSender implements NotificationSenderInterface { public function send(Notification $notification) { // 发送电子邮件... } } $smsNotificationSender = new SMSNotificationSender(); $emailNotificationSender = new EmailNotificationSender(); $notification = new Notification( new UserId(17466), new Subject('Demo notification'), new Message('Very long message ... over 160 characters.') ); $smsNotificationSender->send($notification); $emailNotificationSender->send($notification);
Es gibt zwei Probleme mit dieser Methode:
Wir können dieses Problem vereinfachen, indem wir Loggerinterface zu einer erforderlichen Abhängigkeit machen:
class Notification { public function __construct( ... ) { /* ... */ } public function getUserId() : UserId { /* ... */ } public function withUserId(UserId $userId) : Notification { return new Notification($userId, $this->subject, $this->message); // 使用新的Notification实例 } public function getSubject() : Subject { /* ... */ } public function withSubject(Subject $subject) : Notification { return new Notification($this->userId, $subject, $this->message); // 使用新的Notification实例 } public function getMessage() : Message { /* ... */ } public function withMessage(Message $message) : Notification { return new Notification($this->userId, $this->subject, $message); // 使用新的Notification实例 } }
Auf diese Weise wird unsere öffentliche Oberfläche weniger verwirrend, und wenn jemand eine neue Instanz von SomeService erstellt, wissen sie, dass die Klasse eine Instanz von Loggerinterface erfordert, sodass sie nicht vergessen, eine Instanz zu injizieren.
Zusätzlich haben wir die IF -Anweisung weggelassen, um zu überprüfen, ob der Protokoll injiziert wurde, was unser Dosen () das Lesen erleichterte und die Möglichkeit von Fehlern leichter zu reduzieren hat, wenn jemand Änderungen daran vorgenommen hat.
Wenn wir irgendwann SomeService ohne Logger verwenden möchten, können wir dieselbe Logik wie die Rückgabeanweisung anwenden, aber nur ein leeres Objekt verwenden: <🎜>
<?php class Notification { private $userId; private $subject; private $message; public function __construct( $userId, $subject, $message ) { $this->userId = $userId; $this->subject = $subject; $this->message = $message; } public function getUserId() { return $this->userId; } public function getSubject() { return $this->subject; } public function getMessage() { return $this->message; } }
letztendlich hat dies den gleichen Effekt wie die Verwendung der optionalen SetLogger () -Methode, aber es erleichtert uns, unseren Code zu befolgen, und verringert die Möglichkeit von Fehlern im Abhängigkeitsinjektionsbehälter.
Um unseren Code zu vereinfachen, ist es am besten, die Anzahl der öffentlichen Methoden in der Klasse auf ein Minimum zu halten. Auf diese Weise wird unsere Code -Nutzung weniger verwirrend, wir behalten weniger Code bei und brechen bei der Wiederaufnahme weniger wahrscheinlich nach rückwärts.
Um die öffentliche Methode auf ein Minimum zu halten, kann sie als öffentliche Methode als Transaktion angesehen werden.
Überweisen Sie beispielsweise Geld zwischen zwei Bankkonten:
<?php declare(strict_types=1); class Notification { private $userId; private $subject; private $message; public function __construct( int $userId, string $subject, string $message ) { $this->userId = $userId; $this->subject = $subject; $this->message = $message; } public function getUserId() : int { return $this->userId; } public function getSubject() : string { return $this->subject; } public function getMessage() : string { return $this->message; } }
Während die zugrunde liegende Datenbank Transaktionen bereitstellen kann, um sicherzustellen, dass die Datenbank nicht verhindern kann, dass wir nicht vergessen, $ conto1- & gt () oder $ Account2 anzurufen, werden wir nicht zurückgezogen, und umgekehrt umgekehrt, umgekehrt, kann die Datenbank nicht verhindern. -& gt; deposit (), was dazu führt, dass der Saldo falsch ist.
Zum Glück können wir dieses Problem leicht lösen, indem wir unsere beiden separaten Methoden durch eine einzelne Transaktionsmethode ersetzen:
class UserId { private $userId; public function __construct(int $userId) { $this->userId = $userId; } public function getValue() : int { return $this->userId; } } class Subject { private $subject; public function __construct(string $subject) { $this->subject = $subject; } public function getValue() : string { return $this->subject; } } class Message { private $message; public function __construct(string $message) { $this->message = $message; } public function getMessage() : string { return $this->message; } } class Notification { /* ... */ public function __construct( UserId $userId, Subject $subject, Message $message ) { $this->userId = $userId; $this->subject = $subject; $this->message = $message; } public function getUserId() : UserId { /* ... */ } public function getSubject() : Subject { /* ... */ } public function getMessage() : Message { /* ... */ } }
Infolgedessen wird unser Code robuster, da nur teilweise die Transaktionen anfälliger für Fehler sind.
Im Gegensatz zu Fehlerverhütungsmechanismen sind Fehlererkennungsmechanismen nicht vorgesehen, um Fehler zu verhindern. Stattdessen sollen sie uns warnen, wenn wir Probleme erkennen.
Sie existieren die meiste Zeit außerhalb unserer Anwendungen und laufen regelmäßig aus, um unseren Code oder spezifische Änderungen an ihnen zu überwachen.
Unit -Test kann sicherstellen, dass der neue Code ordnungsgemäß funktioniert, aber er kann auch dazu beitragen, dass vorhandener Code immer noch wie erwartet funktioniert, wenn jemand einen Teil des Systems refaktoren.
Da jemand möglicherweise immer noch vergessen, unsere Unit -Tests tatsächlich durchzuführen, wird empfohlen, Dienste wie Travis CI und GitLab CI zu verwenden, um sie automatisch auszuführen, wenn er Änderungen vornimmt. Auf diese Weise werden Entwickler automatisch benachrichtigt, wenn große Änderungen auftreten, was uns auch hilft, sicherzustellen, dass die Änderungen bei der Überprüfung von Pull -Anfragen erwartet funktionieren.
Abgesehen von der Fehlererkennung sind Unit -Tests auch eine großartige Möglichkeit, Beispiele dafür anzugeben, wie ein bestimmter Teil des Codes zu erwarten ist, was wiederum verhindert, dass andere Personen bei der Verwendung unseres Codes Fehler machen.
Da wir möglicherweise immer vergessen, genügend Tests zu schreiben, kann es von Vorteil sein, Dienste wie Coveralls zu verwenden, um beim Ausführen von Unit -Tests automatisch Codeabdeckungsberichte zu generieren. Wenn unsere Codeabdeckung sinkt, sendet Coveralls uns Benachrichtigungen, damit wir einige Unit -Tests hinzufügen können und wir auch sehen können, wie sich unsere Codeabdeckung im Laufe der Zeit ändert.
Ein weiterer besserer Weg, um sicherzustellen, dass wir über genügend Unit -Tests für unseren Code verfügen, besteht darin, einige Mutationstests wie die Verwendung von Humbug einzurichten. Wie der Name schon sagt, sollen diese Tests überprüfen, ob wir über ausreichende Codeabdeckungen verfügen, indem wir unseren Quellcode geringfügig ändern, dann unsere Unit -Tests ausführen und sicherstellen, dass die relevanten Tests aufgrund von Mutationen fehlschlagen.
Bei Verwendung von Code -Abdeckungsberichten und Mutationstests können wir sicherstellen, dass unsere Unit -Tests genügend Code abdecken, um unerwartete Fehler oder Fehler zu verhindern.
Codeanalysatoren können Fehler in Anwendungen frühzeitig im Entwicklungsprozess erkennen. Beispielsweise verwenden IDEs wie PHPSTORM -Code -Analyseure, um uns vor Fehlern zu warnen und Vorschläge zu geben, wenn wir unseren Code schreiben. Diese reichen von einfachen Syntaxfehlern bis hin zur Erkennung wiederholter Codes.
Zusätzlich zu den integrierten Analysatoren in den meisten IDEs können Drittanbieter oder sogar benutzerdefinierte Analysatoren in den Build-Prozess der Anwendung aufgenommen werden, um spezifische Probleme zu ermitteln. Eine nicht exexhautive Liste von Analysatoren, die für PHP-Projekte geeignet sind, finden Sie in Exakat/PHP-Static-Analyse-Tools, die von Codierungsstandardanalysatoren bis hin zu Analysatoren reichen, die nach Sicherheitslücken suchen.
Online -Lösungen wie Sensiolabs -Erkenntnisse.
Im Gegensatz zu den meisten anderen Fehlererkennungsmechanismen können Protokollnachrichten uns helfen, Fehler in der Anwendung zu erkennen, wenn sie in Echtzeit in der Produktion ausgeführt werden.
Natürlich ist unser Code zuerst erforderlich, um die Nachricht tatsächlich aufzuzeichnen, wenn eine unerwartete Situation auftritt. Auch wenn unser Code Holzfäller unterstützt, kann es leicht sein, alles zu vergessen, während sie sie einrichten. Daher sollten wir versuchen, optionale Abhängigkeiten zu vermeiden (siehe oben).
Während die meisten Anwendungen zumindest einige Nachrichten aufzeichnen, werden die von ihnen bereitgestellten Informationen wirklich interessant, wenn sie proaktiv analysiert und überwacht, indem sie Tools wie Kibana oder Nagios analysieren. Solche Tools geben uns Einblicke in die Fehler und Warnungen, die in Anwendungen auftreten, wenn Benutzer die Anwendung aktiv verwenden, anstatt wenn sie intern testen. Wir haben einen hervorragenden Artikel über die Überwachung von PHP -Anwendungen mit diesem Elch -Stack.
Einige Fehler werden häufig unterdrückt, selbst wenn sie aktiv Fehlermeldungen anmelden. Immer wenn ein "wiederherstellbarer" Fehler auftritt, läuft PHP tendenziell weiter so, als ob er uns helfen möchte, indem er die Anwendung läuft. Fehler sind jedoch häufig sehr nützlich, wenn sie neue Funktionen entwickeln oder testen, da sie normalerweise Fehler in unserem Code anzeigen.
Aus diesem Grund warnen Sie, wenn sie feststellen, dass Sie @ -Unterdrückungsfehler verwenden, da sie Fehler ausblenden können, die unvermeidlich wieder auftauchen, sobald ein Besucher die Anwendung tatsächlich verwendet.
Im Allgemeinen ist es am besten, die ERROR_REPORTING -Ebene von PHP auf e_all festzulegen, so dass selbst die geringsten Warnungen gemeldet werden. Stellen Sie jedoch sicher, dass diese Nachrichten irgendwo aufgezeichnet und vor dem Benutzer versteckt sind, damit vertrauliche Informationen über die Anwendungsarchitektur oder die potenziellen Sicherheitslücken nicht dem Endbenutzer ausgesetzt sind.
Aktivieren Sie neben der ERROR_REPORTING -Konfiguration immer wieder strict_types so, dass PHP nicht versucht, die Funktionsparameter automatisch auf den erwarteten Typ zu gießen, da dies der Konvertieren von einem Typ zu einem anderen ist (z. B. von Float -Runding -Fehlern auf Int int int konvertieren ) Normalerweise zu schwer zu erfimmenden Fehlern.
Da Poka Yoke eher ein Konzept als eine bestimmte Technologie ist, kann es auch auf Bereiche außerhalb von PHP angewendet werden (aber mit PHP bezogen).
Auf Infrastrukturebene können Tools wie Vagrant verwendet werden, um die gleichen Entwicklungseinstellungen wie die Produktionsumgebung zu teilen, was viele Fehler verhindern kann.
Die Verwendung von Serverbuilding wie Jenkins und GOCD kann auch bei der Bereitstellung von Änderungen an unseren Anwendungen dazu beitragen, dass dies häufig eine große Anzahl notwendiger Schritte umfasst, die von der Anwendung abhängen, die leicht vergessen werden können.
Beim Erstellen von REST -APIs können wir Poka Yoke in Verbindung verwenden, um unsere API zu vereinfachen. Zum Beispiel können wir sicherstellen, dass ein Fehler immer zurückgegeben wird, wenn unbekannte Parameter in der URL -Abfrage oder in der Anforderungsbehörde übergeben werden. Dies mag seltsam erscheinen, weil wir offensichtlich vermeiden wollen, unseren API -Kunden zu "brechen", aber es ist normalerweise besser, Entwickler so bald wie möglich über die falsche Verwendung zu warnen, damit Fehler frühzeitig im Entwicklungsprozess repariert werden können.
Zum Beispiel könnte es einen Farbparameter auf unserer API geben, aber jemand, der unsere API verwendet, kann versehentlich den Farbparameter verwenden. Ohne Warnungen kann dieser Fehler leicht in die Produktion gehen, bis der Endbenutzer dies aufgrund eines unerwarteten Verhaltens bemerkt. Um zu verstehen, wie man eine API baut, die Sie später nicht enttäuscht, kann ein gutes Buch helfen.
Effektiv sind alle Anwendungen auf mindestens einer benutzerdefinierten Konfiguration beruhen. In der Regel bevorzugen Entwickler, so viele Standardwerte wie möglich für Konfigurationen bereitzustellen. Die Konfiguration einer Anwendung ist daher weniger Arbeit.
Wie die obigen Farb- und Farbbeispiele ist es jedoch einfach, Konfigurationsparameter falsch einzugeben, wodurch unsere Anwendung versehentlich auf den Standardwert zurückfällt. Es ist schwierig, solche Fehler nachzuverfolgen, wenn die Anwendung keinen Fehler macht, und der beste Weg, um einen Fehler für die falsche Konfiguration zu werfen, besteht darin, überhaupt keine Standardwerte bereitzustellen und sofort einen Fehler zu werfen, wenn Konfigurationsparameter fehlen.
Poka Yoke -Konzept kann auch angewendet werden, um Benutzerfehler zu verhindern oder zu erkennen. In der Zahlungssoftware kann beispielsweise ein Scheck -Bit -Algorithmus verwendet werden, um das vom Benutzer eingegebene Konto zu überprüfen. Dies verhindert, dass Benutzer versehentlich ein Konto mit einem Tippfehler eingeben.
Während Poka Yoke eher ein Konzept als ein bestimmter Satz von Tools ist, können wir verschiedene Prinzipien auf unsere Code- und Entwicklungsprozesse anwenden, um sicherzustellen, dass Fehler so früh wie möglich verhindert oder erkannt werden. Oft sind diese Mechanismen spezifisch für die Anwendung selbst und ihre Geschäftslogik, aber wir können einige einfache Techniken und Tools verwenden, um einen fehlerhafteren Code zu gestalten.
Das Wichtigste ist, dass wir zwar offensichtlich Fehler in der Produktion vermeiden möchten, aber in der Entwicklung sehr nützlich sind und wir keine Angst haben sollten, sie so schnell wie möglich zu erhöhen, damit Fehler leichter nachverfolgt werden können. Diese Fehler können vom Code selbst oder durch separate Prozesse, die getrennt von unserer Anwendung ausgeführt werden, und die Überwachung von außen angehoben werden.
Um Fehler weiter zu reduzieren, sollten wir uns bemühen, die öffentliche Schnittstelle des Codes so einfach und lösch wie möglich zu gestalten.
Wenn Sie andere Tipps zur Anwendung von Poka Yoke auf PHP -Entwicklung oder allgemeine Programmierung haben, können Sie die Kommentare gerne teilen!
poka-yoke ist ein japanischer Begriff, der als "Fehlerprävention" übersetzt. Im Zusammenhang mit der Programmierung handelt es sich um einen defensiven Designansatz, der zu verhindern ist, dass Fehler auftreten. Es umfasst die Implementierung von Sicherheitsmaßnahmen, um Fehler zu vermeiden und sicherzustellen, dass Funktionen korrekt verwendet werden. Der Hauptzweck von Poka-Yoke bei der Programmierung ist es, die Qualität der Software zu verbessern und Fehler zu reduzieren und so Zeit und Ressourcen während des Entwicklungsprozesses zu sparen.
herkömmliche Programmiermethoden konzentrieren sich normalerweise auf das Erstellen von Funktionscode, Fehlerbehandlung und Fehlerbehebung werden normalerweise nach der ersten Entwicklung durchgeführt. Andererseits verfolgt Poka-yoke einen aktiven Ansatz und kombiniert Fehlerverhütungsmechanismen in seiner eigenen Entwicklungsphase. Dies führt zu einem leistungsstärkeren und zuverlässigeren Code, der die Notwendigkeit einer Menge Debugging und Testen verringert.
Ja, Poka-Yoke ist ein Konzept, das auf jede Programmiersprache angewendet werden kann. Es ist kein spezifisches Werkzeug oder eine bestimmte Technologie, sondern eine Denkweise oder eine Methode der Programmierung. Unabhängig davon, welche Sprache Sie verwenden, können Sie das Poka-Yoke-Prinzip implementieren, um Ihren Code fehlerresistenter zu gestalten.
Beispiele für Poka-Yoke in der Programmierung umfassen die Eingabeüberprüfung (um sicherzustellen ) Die Standardaktion für Schäden).
Durch die Verhinderung von Fehlern während der Entwicklungsphase hilft Poka-Yoke, die Gesamtqualität von Softwareprodukten zu verbessern. Es reduziert die Anzahl der Fehler und Defekte, was zu einer stabileren und zuverlässigeren Software führt. Dies verbessert nicht nur die Benutzererfahrung, sondern verringert auch die Kosten und die Zeit des Debuggens und der Wartung.
Während der Implementierung von Poka-Yoke kann während der Entwicklungsphase einige zusätzliche Zeit in Anspruch nehmen. Auf lange Sicht kann es viel Zeit sparen. Durch Verhinderung von Fehlern, bevor sie auftreten, verkürzt dies die Zeit, die für das Debuggen und Fixieren von Fehlern aufgewendet wird, wodurch die Lieferzeit verkürzt und die Entwicklungseffizienz verbessert wird.
im Hersteller kann Poka-Yoke dazu beitragen, Fehler und Defekte zu verhindern und so Produkte zu höherer Qualität zu produzieren. Es kann auch die Effizienz und Produktivität steigern, indem die Zeit und die Ressourcen für Nacharbeiten und Reparaturen verkürzt werden.
Um mit der Implementierung von Poka-Yoke in Ihrer Programmierpraxis zu beginnen, müssen Sie zunächst gemeinsame Fehler oder potenzielle Fehlerpunkte in Ihrem Code identifizieren. Entwickeln Sie dann Strategien, um diese Fehler zu verhindern, oder behandeln Sie sie anmutig, wenn sie auftreten. Dies kann die Eingangsüberprüfung, Behauptungen, fehlgesichtige Standardeinstellungen oder andere Fehlerverhütungstechniken umfassen.
Ja, Poka-Yoke kann effektiv für die agile Entwicklung eingesetzt werden. Tatsächlich passt es gut zum agilen Prinzip (häufige Lieferung von Runnable-Software), da es hilft, sicherzustellen, dass jede Iteration der Software so fehlerfrei wie möglich ist.
Nein, Poka-Yoke ist für Projekte jeder Größe von Vorteil. Selbst für kleine Projekte kann das Verhinderung von Fehlern während der Entwicklungsphase Zeit und Ressourcen sparen und höhere Endprodukte produzieren.
Das obige ist der detaillierte Inhalt vonPoka Yoke - Sparen von Projekten mit hyper -defensiver Programmierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!