Privatunterricht. Versteckt in PHP

In PHP gibt es wie in den meisten anderen OOP-Sprachen Sichtbarkeitsmodifikatoren. Dies sind die Schlüsselwörter public, protected und private. Sie gelten jedoch ausschließlich für Eigenschaften, Methoden oder Konstanten. Diese Modifikatoren hängen eng mit der Fähigkeit zusammen, Daten zu kapseln. Es ist erwähnenswert, dass in Sprachen wie Java, C #, go ( https://golang.org/doc/go1.4#internalpackages ), Ruby ( https://habr.com/post/419969/ ), Crystal ( https : //crystal-lang.org/reference/syntax_and_semantics/visibility.html ) Es ist möglich, den Umfang von Paketen (Klassen) oder Klassen \ Typen einzuschränken . In PHP gibt es keine Möglichkeit, den Umfang für Klassen einzuschränken - auf jede verbundene Klasse kann von jeder anderen Klasse aus zugegriffen werden. Sie können diese Funktion jedoch mit verschiedenen Tricks emulieren.


Warum möglicherweise ein Verstecken auf Klassenebene erforderlich ist:


  • Serviceklassen (Helfer) der Bibliothek - Verunreinigen Sie die Bibliotheks-API nicht mit bedeutungslosen internen Klassen.
  • Kapselung mit Verschleierung interner Objekte der "Geschäftslogik", zum Beispiel Verbot der direkten Erzeugung abhängiger Objekte unter Umgehung einer allgemeineren Klasse.

Separat können wir die Aufteilung "großer" Klassen in kleine Objekte unterscheiden. Es wird empfohlen, die Komplexität (und die Anzahl der Zeilen) sowohl einzelner Methoden als auch Klassen zu begrenzen. Die Anzahl der Zeilen hier ist einer der Marker, für die die Klassenmethode oder die Klasse selbst unnötige Verantwortung übernimmt. Beim Refactoring einer öffentlichen Methode verschieben wir Teile davon in private \ protected-Methoden. Wenn jedoch aus dem einen oder anderen Grund die Klasse wächst und wir eine separate Entität von ihr trennen, werden diese sehr privaten \ geschützten Klassen in eine separate Klasse übertragen, wodurch wir indirekt den Zugriff auf Methoden öffnen, die zuvor auf den Umfang einer Klasse beschränkt waren.


Nun die eigentlichen Methoden, um Vertuschungen selbst zu emulieren.


Auf der Ebene der Codeausführungsvereinbarung


Mithilfe von PHPDoc-Kommentaren können Sie eine Klasse, ein Merkmal oder eine Schnittstelle als internal markieren ( http://docs.phpdoc.org/references/phpdoc/tags/internal.html ). Einige IDEs (wie PhpStorm) können solche Bezeichnungen jedoch verstehen.


Verwenden Sie Laufzeitinformationen


Zur Laufzeit können Sie überprüfen, von wo der Klassenkonstruktor aufgerufen wurde. debug_backtrace Sie beispielsweise die Methode debug_backtrace ( http://php.net/manual/ru/function.debug-backtrace.php ) oder verwenden Sie die ähnliche Xdebug-Funktionalität, um den Code in der dev \ test-Umgebung zu steuern. Ein Beispiel für eine formalisierte Lösung finden Sie hier ( https://coderwall.com/p/ixvnga/how-emulate-private-class-concept-in-php ).


mit debug_backtrace
 /** * The private class */ final class PrivateClass { /** * defines the only class able to instantiate the current one * * @var string */ private $allowedConsumer = 'AllowedPrivateClassConsumer'; /** * constructor * * @throws Exception */ public function __construct() { /** * here comes the privacy filter, it could be extracted to a private method * or to a static method of another class with few adjustments */ $builder = debug_backtrace(); if (count($builder) < 2 || !isset($builder[1]['class']) || $builder[1]['class'] !== $this->allowedConsumer) { throw new Exception('Need to be instantiated by '.$this->allowedConsumer); } } } 

Verwenden Sie anonyme Klassen


Eine relativ neue Funktionalität in PHP sind anonyme Klassen ( http://php.net/manual/ru/language.oop5.anonymous.php ). Nachdem wir die anonyme Klasse in der geschützten Methode beschrieben haben, versuchen wir, sie auszublenden. Um die Definition einer Klasse innerhalb einer Funktion nicht durcheinander zu bringen, können Sie die "private" Klasse in einer separaten Datei als abstrakt beschreiben und bereits in der Definition einer anonymen Klasse erweitern. Ein gutes Beispiel für die Verwendung dieser Methode finden Sie unter diesem Link ( https://markbakeruk.net/2018/06/25/using-php-anonymous-classes-as-package-private-classes/ ).


Basierend auf dem gefundenen Material ist es klar, dass die Funktionalität des Ausblendens von Klassen in gewissem Maße gefordert ist (und in vielen Sprachen vorhanden ist), jedoch ist die Praxis ihrer Verwendung sehr begrenzt, möglicherweise aufgrund der fehlenden Beschreibung von Beispielen in verschiedenen "Best Practices", Sammlungen von Vorlagen und ähnlichen Quellen. Was meiner Meinung nach ziemlich seltsam ist, dass es darum geht, die internen Methoden und Eigenschaften von Objekten zu verbergen, aber fast niemand achtet darauf, dass größere logische Codeteile in Form von Dienstprogrammbibliotheksklassen oder Domänendomänen im globalen Sichtbarkeitsraum verbleiben.

Source: https://habr.com/ru/post/de435894/


All Articles