Kelas privat. Bersembunyi di php

Di php, seperti di sebagian besar bahasa OOP lainnya, ada pengubah visibilitas. Ini adalah kata kunci publik, dilindungi, dan pribadi. Tetapi mereka berlaku secara eksklusif untuk properti, metode, atau konstanta. Pengubah ini terkait erat dengan kemampuan untuk merangkum data. Perlu dicatat bahwa dalam bahasa seperti 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 ) dimungkinkan untuk membatasi ruang lingkup paket (paket) atau kelas \ tipe. Dalam php tidak ada cara untuk membatasi ruang lingkup kelas - kelas yang terhubung dapat diakses dari kelas lain. Namun, Anda dapat meniru fitur ini menggunakan beberapa trik.


Mengapa persembunyian tingkat kelas mungkin diperlukan:


  • Kelas layanan (pembantu) perpustakaan - jangan membuang API perpustakaan dengan kelas internal yang tidak berarti.
  • Enkapsulasi dengan penyembunyian objek internal "logika bisnis", misalnya, larangan generasi langsung objek dependen melewati kelas yang lebih umum.

Secara terpisah, kita dapat membedakan partisi kelas "besar" menjadi objek kecil. Ini adalah praktik yang baik untuk membatasi kompleksitas (dan jumlah baris) metode dan kelas individu. Jumlah baris di sini berlaku sebagai salah satu penanda bahwa metode kelas atau kelas itu sendiri mengambil tanggung jawab yang tidak perlu. Saat refactoring metode publik, kami memindahkan sebagiannya ke metode private \ protected. Tetapi ketika karena satu dan lain alasan kelas tumbuh dan kami memisahkan entitas yang terpisah darinya, kelas yang sangat pribadi \ dilindungi ini ditransfer ke kelas yang terpisah, sehingga kami secara tidak langsung membuka akses ke metode yang sebelumnya terbatas pada ruang lingkup satu kelas.


Sekarang metode sebenarnya untuk meniru itu sendiri.


Pada tingkat perjanjian eksekusi kode


Menggunakan komentar PHPDoc, Anda dapat menandai kelas, ciri atau antarmuka sebagai internal ( http://docs.phpdoc.org/references/phpdoc/tags/internal.html ). Namun, beberapa IDE (seperti PhpStorm) dapat memahami label tersebut.


Gunakan informasi runtime


Saat runtime, Anda dapat memeriksa dari mana konstruktor kelas dipanggil. Misalnya, melalui metode debug_backtrace ( http://php.net/manual/ru/function.debug-backtrace.php ) atau gunakan fungsi Xdebug serupa untuk mengontrol kode di lingkungan dev \ test. Contoh dari solusi formal ada di sini ( https://coderwall.com/p/ixvnga/how-emulates-private-class-concept-in-php ).


menggunakan 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); } } } 

Gunakan kelas anonim


Fungsionalitas yang relatif baru di php adalah kelas anonim ( http://php.net/manual/ru/language.oop5.anonymous.php ). Setelah menggambarkan kelas anonim di dalam metode yang dilindungi, kami berusaha menyembunyikannya. Agar tidak membuat kekacauan definisi kelas di dalam suatu fungsi, Anda dapat menggambarkan kelas "pribadi" dalam file terpisah sebagai abstrak, dan sudah memperluasnya dalam definisi kelas anonim. Contoh yang baik untuk menggunakan metode ini ada di tautan ini ( https://markbakeruk.net/2018/06/25/using-php-anonymous-classes-as-package-private-classes/ ).


Berdasarkan bahan yang ditemukan, jelas bahwa fungsionalitas dari kelas bersembunyi dalam beberapa cara dituntut (dan ada dalam banyak bahasa), tetapi praktik penggunaannya sangat terbatas, mungkin karena kurangnya deskripsi contoh dalam berbagai "praktik terbaik", koleksi template dan sumber serupa. Yang, menurut saya, agak aneh, bahwa ada penekanan pada menyembunyikan metode internal dan sifat-sifat objek, tetapi hampir tidak ada yang memperhatikan fakta bahwa potongan-potongan kode logis yang lebih besar dalam bentuk kelas perpustakaan utilitas atau domain domain tetap berada dalam ruang visibilitas global.

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


All Articles