No php, como na maioria das outras linguagens OOP, existem modificadores de visibilidade. Estas são as palavras-chave pública, protegida e privada. Mas eles se aplicam exclusivamente a propriedades, métodos ou constantes. Esses modificadores estão intimamente relacionados à capacidade de encapsular dados. Vale ressaltar que em idiomas como 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 ) é possível limitar o escopo dos pacotes (pacotes) ou classes \ tipos. No php, não há como limitar o escopo das classes - qualquer classe conectada é acessível a partir de qualquer outra classe. No entanto, você pode emular esse recurso usando vários truques.
Por que a ocultação em nível de classe pode ser necessária:
- Classes de serviço (auxiliares) da biblioteca - não desarrume a API da biblioteca com classes internas sem sentido.
- Encapsulamento com ocultação de objetos internos da "lógica de negócios", por exemplo, proibição de geração direta de objetos dependentes ignorando uma classe mais geral.
Separadamente, podemos distinguir a partição de classes "grandes" em objetos pequenos. É uma boa prática limitar a complexidade (e o número de linhas) de métodos e classes individuais. O número de linhas aqui segue como um dos marcadores que o método da classe ou a própria classe assumem responsabilidades desnecessárias. Ao refatorar um método público, movemos partes dele para métodos privados \ protegidos. Mas quando, por um motivo ou outro, a classe cresce e nós separamos uma entidade separada, essas classes \ privadas muito protegidas são transferidas para uma classe separada, assim, indiretamente, abrimos o acesso a métodos anteriormente limitados ao escopo de uma classe.
Agora, os métodos reais de emular os próprios encobrimentos.
Usando os comentários do PHPDoc, você pode marcar uma classe, característica ou interface como internal
( http://docs.phpdoc.org/references/phpdoc/tags/internal.html ). No entanto, alguns IDEs (como PhpStorm) podem entender esses rótulos.
No tempo de execução, você pode verificar de onde o construtor de classe foi chamado. Por exemplo, através do método debug_backtrace
( http://php.net/manual/ru/function.debug-backtrace.php ) ou use a funcionalidade Xdebug semelhante para controlar o código no ambiente dev \ test. Um exemplo de solução formalizada está aqui ( https://coderwall.com/p/ixvnga/how-emulates-private-class-concept-in-php ).
usando debug_backtrace final class PrivateClass { private $allowedConsumer = 'AllowedPrivateClassConsumer'; public function __construct() { $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); } } }
Use classes anônimas
Uma funcionalidade relativamente nova no php são as classes anônimas ( http://php.net/manual/ru/language.oop5.anonymous.php ). Tendo descrito a classe anônima dentro do método protegido, procuramos ocultá-la. Para não bagunçar a definição de uma classe dentro de uma função, você pode descrever a classe "private" em um arquivo separado como abstrato, e já expandi-la na definição de uma classe anônima. Um bom exemplo do uso desse método está neste link ( https://markbakeruk.net/2018/06/25/using-php-anonymous-classes-as-package-private-classes/ ).
Com base no material encontrado, fica claro que a funcionalidade das classes ocultas é de alguma forma exigida (e existe em várias línguas), mas a prática de seu uso é muito limitada, possivelmente devido à falta de descrição de exemplos em várias "melhores práticas", coleções de modelos e fontes semelhantes. O que, na minha opinião, é bastante estranho, que há uma ênfase em ocultar os métodos e propriedades internos dos objetos, mas quase ninguém presta atenção ao fato de que grandes partes lógicas de código na forma de classes de bibliotecas de utilidade ou domínios de domínio permanecem no espaço de visibilidade global.