Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

[Dúvida] Public vs Private vs Set() vs @property-read vs readonly

Minha dúvida conversa com o que foi exposto nesta aqui: https://cursos.alura.com.br/forum/topico-duvida-sobre-__get-e-__set-em-relacao-ao-principio-de-encapsulamento-281707

Já entendi que na programação orientada a objeto você cria objetos a partir de classes que terão propriedades e métodos cujo acesso pode ser controlado pelo princípio do encapsulamento.

Porém, nessa última aula eu me perdi com relação aos conceitos e ao sentido das coisas:

  • O sentido de você criar uma propriedade e colocá-la como privada é restringir o acesso a ela apenas através dos métodos públicos disponíveis. Ok.
  • Se você deixar uma propriedade como pública ela pode ser alterada à vontade sem precisar de métodos específicos. Ok.
  • Mas se você tiver usado o método set() você pode alterar até mesmo as propriedades privadas e protegidas. Tá... Ok.
  • Então em tese se uma pessoa define os atributos de uma classe como privados mas deixa o método set() como público e com um escopo capaz de alterar o valor de qualquer atributo, então teria o mesmo efeito de colocar os atributos como públicos?
  • Mas espera aí, se mesmo com os atributos privados e o método set() irrestrito, eu colocar no topo da classe o comentário /** @property-read $atributo*/ eu não vou conseguir usar o método set() para alterar o $atributo, correto?
  • Então isso teria o mesmo efeito de colocar os atributos como privados e sem método set()?
  • Por que então não só deixar os métodos privados? Qual é o sentido de usar @property-read?
  • E é porque ainda tem o redonly (na definição do atributo) que eu nem sei se está hierarquicamente acima ou abaixo de qualquer um desses recursos. Qual a diferença entre usar /** @property-read $atributo*/ e readonly $atributo?
  • Se é pra deixar um atributo acessível e modificável por que não só colocá-lo como público ao invés de usar set()?
  • A única vantagem do set() em relação a qualquer outro setter é não ter que chamar o método setter diretamente? Ex: $objeto->atributo = "valor"; VS $objeto-> alterarAtributo("valor"); é isso? A vantagem é a economia de caracteres usados?

Public vs Private vs Set() vs @property-read vs readonly

A meu ver parece que criam uma regra depois criam uma exceção depois a exceção da exceção e por aí vai.

  • Alguém poderia por favor me explicar qual é o sentido de cada um desses recursos e sua hierarquia?

E sim, eu sei que isso depende da regra de negócio da aplicação, mas o que eu não entendo é o porquê de haver recursos que parecem fazer a mesma coisa.

  • Qual é a vantagem de um em relação ao outro e quando usar cada um?
3 respostas

Então em tese se uma pessoa define os atributos de uma classe como privados mas deixa o método set() como público e com um escopo capaz de alterar o valor de qualquer atributo, então teria o mesmo efeito de colocar os atributos como públicos?

Sim. Mas você tem um controle maior. Exemplo: tenho uma propriedade (privada) $nome um método (público) alteraNome que modifica o valor da propriedade. Se no futuro houver uma nova regra dizendo que todo nome precisa ter pelo menos 5 caracteres, todo acesso a essa propriedade está centralizado no código da classe, entende? :-)

Mas espera aí, se mesmo com os atributos privados e o método set() irrestrito, eu colocar no topo da classe o comentário /** @property-read $atributo*/ eu não vou conseguir usar o método set() para alterar o $atributo, correto?

Incorreto. /** @property-read $atributo */ é apenas um comentário e o PHP simplesmente ignora isso. Sua IDE pode te avisar que $atributo não deve ser escrito, mas o PHP não fará nada.

Então isso teria o mesmo efeito de colocar os atributos como privados e sem método set()?

Não

E é porque ainda tem o redonly (na definição do atributo) que eu nem sei se está hierarquicamente acima ou abaixo de qualquer um desses recursos. Qual a diferença entre usar /** @property-read $atributo*/ e readonly $atributo?

/** @property-read ... */ não é interpretado pelo PHP. Uma propriedade readonly só pode ter um valor atribuído uma vez. Então um método setter em uma propriedade readonly vai falhar.

Se é pra deixar um atributo acessível e modificável por que não só colocá-lo como público ao invés de usar set()?

A primeira parte dessa resposta deve explicar um pouco o motivo disso. :-)

A única vantagem do set() em relação a qualquer outro setter é não ter que chamar o método setter diretamente? Ex: $objeto->atributo = "valor"; VS $objeto-> alterarAtributo("valor"); é isso? A vantagem é a economia de caracteres usados?

Quando você diz set(), se refere ao método mágico __set? Se sim: https://dias.dev/2023-08-11-metodos-magicos-php/ Não é a economia de caracteres. É para deixar a existência do método implícita para quem usa. É um detalhe de design de código mesmo. Mas em funcionamento, são sim equivalentes esses 2 exemplos que você deu.


Bom, espero que essas respostas tenham clareado um pouco o assunto. Se continuar com dúvida, só dizer. Senão, não se esquece de marcar o tópico como resolvido. :-D

Oi Vinícius, obrigado por tirar minha dúvida.

Então, se eu entendi direito, a resposta geral para o uso dos recursos é basicamente: Controle e Design.

É isso mesmo?

solução!

A resposta para tudo em OO é isso. :-D

É perfeitamente possível criar uma aplicação sem orientação a objetos. Mas com OO nós temos recursos que tornam o design do nosso código mais fácil de ler, manter, etc.