Como você acessaria as propriedades do objeto dentro de um método de objeto?[fechado]

StackOverflow https://stackoverflow.com/questions/126

  •  08-06-2019
  •  | 
  •  

Pergunta

Qual é a maneira "purista" ou "correta" de acessar as propriedades de um objeto de dentro de um método de objeto que não é um método getter/setter?

Eu sei que de fora do objeto você deveria usar um getter/setter, mas de dentro você faria:

Java:

String property = this.property;

PHP:

$property = $this->property;

ou você faria:

Java:

String property = this.getProperty();

PHP:

$property = $this->getProperty();

Perdoe-me se meu Java está um pouco errado, já faz um ano que não programo em Java...

EDITAR:

Parece que as pessoas estão assumindo que estou falando apenas de variáveis/propriedades privadas ou protegidas.Quando aprendi OO, fui ensinado a usar getters/setters para cada propriedade, mesmo que fosse pública (e na verdade me disseram para nunca tornar pública nenhuma variável/propriedade).Portanto, posso estar partindo de uma suposição falsa desde o início.Parece que as pessoas que respondem a esta pergunta talvez estejam dizendo que você deveria ter propriedades públicas e que elas não precisam de getters e setters, o que vai contra o que me ensinaram e o que eu estava falando, embora talvez isso precise ser discutido como bem.Esse é provavelmente um bom tópico para uma pergunta diferente ...

Foi útil?

Solução

Isso tem potencial de guerra religiosa, mas me parece que se você estiver usando um getter/setter, você também deve usá-lo internamente - usar ambos levará a problemas de manutenção no futuro (por exemplo,alguém adiciona código a um setter que precisa para ser executado sempre que essa propriedade for definida e a propriedade estiver sendo definida internamente sem que o setter seja chamado).

Outras dicas

Pessoalmente, sinto que é importante permanecer consistente.Se você tiver getters e setters, use-os.A única vez que eu acessaria um campo diretamente seria quando o acessador tivesse muita sobrecarga.Pode parecer que você está sobrecarregando seu código desnecessariamente, mas certamente pode evitar muita dor de cabeça no futuro.O exemplo clássico:

Mais tarde, você pode querer mudar a forma como esse campo funciona.Talvez deva ser calculado instantaneamente ou talvez você queira usar um tipo diferente para o armazenamento de apoio.Se você estiver acessando propriedades diretamente, uma mudança como essa pode quebrar uma enorme quantidade de código de uma só vez.

Estou bastante surpreso com o quão unânime é o sentimento de que getters e setters são bons e bons.Sugiro o artigo incendiário de Allen Holub "Getters e setters são maus".É verdade que o título tem um valor chocante, mas o autor apresenta argumentos válidos.

Essencialmente, se você tiver getters e setters para cada campo privado, você está tornando esses campos tão bons quanto públicos.Seria muito difícil alterar o tipo de campo privado sem efeitos cascata para todas as classes que chamam isso getter.

Além disso, do ponto de vista estritamente OO, os objetos deveriam responder a mensagens (métodos) que correspondam à sua (espero) responsabilidade única.A grande maioria de getters e setters não fazem sentido para os seus objetos constituintes;Pen.dispenseInkOnto(Surface) faz mais sentido para mim do que Pen.getColor().

Getters e setters também incentivam os usuários da classe a solicitar alguns dados ao objeto, realizar um cálculo e, em seguida, definir algum outro valor no objeto, mais conhecido como programação processual.Seria melhor você simplesmente dizer ao objeto para fazer o que você estava fazendo em primeiro lugar;também conhecido como Especialista em Informação idioma.

Getters e setters, entretanto, são males necessários na fronteira das camadas – UI, persistência e assim por diante.Acesso restrito aos componentes internos de uma classe, como a palavra-chave friend do C++, o acesso protegido por pacote do Java, o acesso interno do .NET e o Padrão de Classe de Amigo pode ajudá-lo a reduzir a visibilidade de getters e setters apenas para aqueles que precisam deles.

Depende de como a propriedade é usada.Por exemplo, digamos que você tenha um objeto aluno que possui uma propriedade name.Você poderia usar seu método Get para extrair o nome do banco de dados, se ele ainda não tiver sido recuperado.Dessa forma você está reduzindo chamadas desnecessárias ao banco de dados.

Agora digamos que você tenha um contador inteiro privado em seu objeto que conta o número de vezes que o nome foi chamado.Você pode querer não usar o método Get de dentro do objeto porque isso produziria uma contagem inválida.

PHP oferece inúmeras maneiras de lidar com isso, incluindo métodos mágicos __get e __set, mas prefiro getters e setters explícitos.Aqui está o porquê:

  1. A validação pode ser colocada em setters (e getters nesse caso)
  2. Intellisense trabalha com métodos explícitos
  3. Não há dúvida se uma propriedade é somente leitura, somente gravação ou leitura-gravação
  4. A recuperação de propriedades virtuais (ou seja, valores calculados) é igual às propriedades normais
  5. Você pode facilmente definir uma propriedade de objeto que nunca é realmente definida em nenhum lugar, e então fica sem documentação

Estou exagerando aqui?

Talvez ;)

Outra abordagem seria utilizar um método privado/protegido para realmente fazer a obtenção (cache/db/etc) e um wrapper público que incremente a contagem:

PHP:

public function getName() {
    $this->incrementNameCalled();
    return $this->_getName();
}

protected function _getName() {
    return $this->name;
}

e então de dentro do próprio objeto:

PHP:

$name = $this->_getName();

Dessa forma, você ainda pode usar esse primeiro argumento para outra coisa (como enviar um sinalizador para usar ou não dados em cache aqui, talvez).

Devo estar perdendo o foco aqui, por que você usaria um getter dentro de um objeto para acessar uma propriedade desse objeto?

Levando isso à conclusão, o getter deve chamar um getter, que deve chamar um getter.

Então, eu diria que dentro de um método de objeto acessar uma propriedade diretamente, especialmente visto que chamar outro método nesse objeto (que apenas acessará a propriedade diretamente de qualquer maneira e depois a retornará) é apenas um exercício inútil e inútil (ou entendi mal a questão ).

Se por "purista" você quer dizer "maior encapsulamento", normalmente declaro todos os meus campos como privados e uso this.field de dentro da própria classe, mas todas as outras classes, incluindo subclasses, acessam o estado da instância usando os getters.

eu diria que é melhor usar os métodos acessadores mesmo dentro do objeto.Aqui estão os pontos que me vêm à mente imediatamente:

1) Deve ser feito no interesse de manter a consistência com os acessos feitos fora do objeto.

2) Em alguns casos, esses métodos acessadores podem fazer mais do que apenas acessar o campo;eles poderiam estar fazendo algum processamento adicional (embora seja raro).Se for esse o caso, ao acessar o campo diretamente você perderia esse processamento adicional e seu programa poderia dar errado se esse processamento fosse sempre feito durante esses acessos

A maneira purista de OO é evitar ambos e seguir o Lei de Deméter usando o Diga, não pergunte abordagem.

Em vez de obter o valor da propriedade do objeto, que casais firmemente as duas classes, use o objeto como parâmetro, por exemplo.

  doSomethingWithProperty() {
     doSomethingWith( this.property ) ;
  }

Onde a propriedade era do tipo nativo, por ex.int, use um método de acesso, nomeie-o para o domínio do problema e não para o domínio de programação.

  doSomethingWithProperty( this.daysPerWeek() ) ;

Isso permitirá que você mantenha o encapsulamento e quaisquer pós-condições ou invariantes dependentes.Você também pode usar o método setter para manter quaisquer pré-condições ou invariantes dependentes, porém não caia na armadilha de nomeá-los setters, volte ao Princípio de Hollywood para nomear ao usar o idioma.

descobri que o uso de setters/getters tornou meu código mais fácil de ler.Também gosto do controle que ele dá quando outras classes usam os métodos e se eu alterar os dados a propriedade irá armazenar.

Campos privados com propriedades públicas ou protegidas.O acesso aos valores deve passar pelas propriedades, e ser copiado para uma variável local caso sejam utilizados mais de uma vez em um método.Se e SOMENTE se você tiver o resto do seu aplicativo totalmente ajustado, aprimorado e otimizado para onde o acesso aos valores passando por suas propriedades associadas se tornou um gargalo (e isso NUNCA acontecerá, eu garanto) você deveria começar considerar deixar qualquer coisa além das propriedades tocar diretamente em suas variáveis ​​de apoio.

Os desenvolvedores .NET podem usar propriedades automáticas para impor isso, já que você nem consegue ver as variáveis ​​de apoio em tempo de design.

Se eu não editar a propriedade, usarei um get_property() método público, a menos que seja uma ocasião especial, como um objeto MySQLi dentro de outro objeto; nesse caso, apenas publicarei a propriedade e me referirei a ela como $obj->object_property.

Dentro do objeto é sempre $this->property para mim.

Depende.É mais uma questão de estilo do que qualquer outra coisa, e não existe uma regra rígida.

Posso estar errado porque sou autodidata, mas NUNCA uso propriedades públicas em minhas classes Java, elas são sempre privadas ou protegidas, de modo que o código externo deve ser acessado por getters/setters.É melhor para fins de manutenção/modificação.E para o código da classe interna ...Se o método getter for trivial, eu uso a propriedade diretamente, mas sempre uso os métodos setter porque poderia facilmente adicionar código para disparar eventos, se desejar.

Bem, parece que com a implementação padrão das propriedades do C# 3.0, a decisão é tomada por você;você PRECISA definir a propriedade usando o configurador de propriedade (possivelmente privado).

Pessoalmente, eu só uso o private member-behind quando não fazer isso faria com que o objeto caísse em um estado inferior ao desejável, como durante a inicialização ou quando o cache/carregamento lento está envolvido.

gostei da resposta de cmculloh, mas parece que o mais correto é a resposta de Greg Hurlman.Use getter/setters o tempo todo se você começou a usá-los desde o início e/ou está acostumado a trabalhar com eles.

Além disso, pessoalmente acho que o uso de getter/setters torna o código mais fácil de ler e depurar posteriormente.

Como afirmado em alguns dos comentários:Às vezes você deveria, às vezes você não deveria.A melhor parte das variáveis ​​privadas é que você pode ver todos os lugares onde elas são usadas quando você altera alguma coisa.Se o seu getter/setter fizer algo que você precisa, use-o.Se não importa você decide.

O caso oposto poderia ser feito: se você usar o getter/setter e alguém alterar o getter/setter, eles terão que analisar todos os lugares onde o getter e o setter são usados ​​internamente para ver se isso atrapalha alguma coisa.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top