Qual é a vantagem de usar getters e setters - que apenas obtêm e configuram - em vez de simplesmente usar campos públicos para essas variáveis?
Se getters e setters estão fazendo algo além do simples get / set, eu posso descobrir isso rapidamente, mas não sou 100% claro sobre como:
public String foo;
é pior do que:
private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }
Considerando que o primeiro leva muito menos código padrão.
Respostas:
Na verdade, existem muitas boas razões para considerar o uso de acessadores em vez de expor diretamente os campos de uma classe - além do argumento do encapsulamento e facilitar as alterações futuras.
Aqui estão algumas das razões pelas quais estou ciente:
fonte
public
métodos de acesso causam duplicação de código e expõem informações. Os acessadores públicos não são necessários para o empacotamento (serialização). Em algumas linguagens (Java), ospublic
acessadores get não podem ter o tipo de retorno alterado sem interromper as classes dependentes. Além disso, acredito que eles vão contra os princípios da OO. Veja também: stackoverflow.com/a/1462424/59087plane.turnTo(dir); plane.setSpeed(spd); plane.setTargetAltitude(alt); plane.getBreaks().release();
eu quero dizerplane.takeOff(alt)
. Quais campos de dados internos precisam ser alterados para colocar o avião notakingOff
modo não são das minhas preocupações. E que outros objetos (breaks
) o método notifica que também não quero saber.Como daqui a duas semanas (meses, anos), quando você perceber que seu levantador precisa fazer mais do que apenas definir o valor, também perceberá que a propriedade foi usada diretamente em 238 outras classes :-)
fonte
Um campo público não é pior que um par getter / setter que não faz nada, exceto retornar o campo e atribuir a ele. Primeiro, é claro que (na maioria dos idiomas) não há diferença funcional. Qualquer diferença deve estar em outros fatores, como manutenção ou legibilidade.
Uma vantagem freqüentemente mencionada dos pares getter / setter, não é. Há uma alegação de que você pode alterar a implementação e seus clientes não precisam ser recompilados. Supostamente, os setters permitem adicionar funcionalidades como validação posteriormente e seus clientes nem precisam saber sobre isso. No entanto, adicionar validação a um levantador é uma alteração em suas condições prévias, uma violação do contrato anterior , que era, simplesmente, "você pode colocar qualquer coisa aqui e pode obter a mesma coisa posteriormente no levantador".
Então, agora que você quebrou o contrato, alterar todos os arquivos da base de código é algo que você deve querer fazer, não evitar. Se você evitá-lo, está assumindo que todo o código assumiu que o contrato para esses métodos era diferente.
Se esse não fosse o contrato, a interface permitiria que os clientes colocassem o objeto em estados inválidos. Esse é exatamente o oposto do encapsulamento. Se esse campo não podia realmente ser definido para nada desde o início, por que a validação não estava lá desde o início?
Esse mesmo argumento se aplica a outras supostas vantagens desses pares de passagem / coleta de coleta: se você decidir posteriormente alterar o valor que está sendo definido, está quebrando o contrato. Se você substituir a funcionalidade padrão em uma classe derivada, além de algumas modificações inofensivas (como log ou outro comportamento não observável), estará quebrando o contrato da classe base. Isso é uma violação do princípio da substituibilidade de Liskov, que é visto como um dos princípios da OO.
Se uma classe tem esses getters e setters burros para todos os campos, então é uma classe que não tem invariantes, nenhum contrato . Esse design é realmente orientado a objetos? Se tudo o que a classe tem são esses getters e setters, é apenas um detentor de dados burros, e os detentores de dados burros devem parecer com detentores de dados burros:
Adicionar pares getter / setter de passagem a essa classe não agrega valor. Outras classes devem fornecer operações significativas, não apenas operações que os campos já fornecem. É assim que você pode definir e manter invariantes úteis.
Existem razões para usar getters e setters, mas se essas razões não existirem, criar pares getter / setter em nome de deuses falsos de encapsulamento não é uma coisa boa. Os motivos válidos para obter getters ou setters incluem as coisas frequentemente mencionadas como as possíveis alterações que você pode fazer posteriormente, como validação ou diferentes representações internas. Ou talvez o valor deva ser legível pelos clientes, mas não gravável (por exemplo, lendo o tamanho de um dicionário); portanto, um getter simples é uma boa opção. Mas essas razões devem estar presentes quando você faz a escolha, e não apenas como algo potencial que você pode querer mais tarde. Esta é uma instância do YAGNI ( você não vai precisar disso ).
fonte
private
campo. Se uma classe não possui criadores, é fácil torná-la imutável.Muitas pessoas falam sobre as vantagens de quem recebe e recebe, mas eu quero bancar o advogado do diabo. No momento, estou depurando um programa muito grande, em que os programadores decidiram criar tudo getters e setters. Pode parecer bom, mas é um pesadelo de engenharia reversa.
Digamos que você esteja pesquisando centenas de linhas de código e se depare com isso:
É um pedaço de código lindamente simples até você perceber que é um criador. Agora, você segue esse configurador e descobre que ele também define person.firstName, person.lastName, person.isHuman, person.hasReallyCommonFirstName e chama person.update (), que envia uma consulta ao banco de dados etc. onde seu vazamento de memória estava ocorrendo.
Compreender um pedaço de código local à primeira vista é uma propriedade importante de boa legibilidade que os getters e os setters tendem a quebrar. É por isso que tento evitá-los quando posso e minimizar o que eles fazem quando os uso.
fonte
person.name = "Joe";
é chamado. Não há nenhum problema no caminho das informações, o destaque da sintaxe mostra que é um campo e a refatoração é mais simples (não é necessário refatorar dois métodos e um campo). Segundo, todos os ciclos cerebrais desperdiçados que pensam "getIsValid ()" ou deveriam ser "isValid ()" etc. podem ser esquecidos. Não consigo pensar em uma única vez em que fui salvo de um bug por um getter / setter.Existem muitas razões. O meu favorito é quando você precisa alterar o comportamento ou regular o que pode definir em uma variável. Por exemplo, digamos que você tenha um método setSpeed (int speed). Mas você quer que você possa definir apenas uma velocidade máxima de 100. Você faria algo como:
Agora, e se EM TODA PARTE do seu código você estivesse usando o campo público e percebesse que precisava do requisito acima? Divirta-se procurando todos os usos do campo público em vez de apenas modificar o seu setter.
Meus 2 centavos :)
fonte
while(speed < 200) { do_something(); accelerate(); }
)myCar.setSpeed(157);
e depois de algumas linhasspeed = myCar.getSpeed();
E agora ... desejo a você uma depuração feliz ao tentar entender o porquêspeed==100
quando deveria ser157
Em um mundo puro, orientado a objetos, getters e setters são um terrível anti-padrão . Leia este artigo: Getters / Setters. Mal. Período . Em poucas palavras, eles incentivam os programadores a pensar em objetos como estruturas de dados, e esse tipo de pensamento é puramente processual (como em COBOL ou C). Em uma linguagem orientada a objetos, não há estruturas de dados, mas apenas objetos que expõem o comportamento (não atributos / propriedades!)
Você pode encontrar mais informações sobre eles na Seção 3.5 de Objetos elegantes (meu livro sobre programação orientada a objetos).
fonte
new Dog()
não é um cachorro. É um objeto que contém informações sobre um cachorro. E para esse uso, é natural poder corrigir um peso gravado incorretamente.Uma vantagem dos acessadores e mutadores é que você pode executar a validação.
Por exemplo, se
foo
fosse público, eu poderia defini-lo facilmentenull
e, em seguida, alguém poderia tentar chamar um método no objeto. Mas não está mais lá! Com umsetFoo
método, eu poderia garantir que issofoo
nunca foi definidonull
.Acessores e mutadores também permitem o encapsulamento - se você não vê o valor uma vez definido (talvez seja definido no construtor e depois usado pelos métodos, mas nunca deveria ser alterado), nunca será visto por ninguém. Mas se você pode permitir que outras classes vejam ou alterem, você pode fornecer o acessador e / ou o mutador adequados.
fonte
Depende do seu idioma. Você marcou isso como "orientado a objetos" em vez de "Java", então gostaria de salientar que a resposta do ChssPly76 depende da linguagem. No Python, por exemplo, não há razão para usar getters e setters. Se você precisar alterar o comportamento, poderá usar uma propriedade, que envolve um getter e um setter em torno do acesso básico ao atributo. Algo assim:
fonte
obj.set_attr('foo')
) são inerentemente superiores aos sinais de igual (obj.attr = 'foo'
). Acesso público é acesso público.obj.attr = 'foo'
apenas define a variável sem qualquer outra coisa acontecendoobj.setAttr('foo')
"apenas define a variável sem que nada aconteça"? Se é um método público, então é um método público. Se você o usar para obter algum efeito colateral, e for público, será melhor poder contar com tudo funcionando como se apenas esse efeito colateral pretendido tivesse acontecido (com todos os outros detalhes de implementação e outros efeitos colaterais, uso de recursos, qualquer que seja , oculto das preocupações do usuário). Isso não é absolutamente diferente com o Python. A sintaxe do Python para obter o efeito é apenas mais simples.Bem, eu só quero acrescentar que, mesmo que algumas vezes sejam necessários para o encapsulamento e a segurança de suas variáveis / objetos, se queremos codificar um programa orientado a objetos real, precisamos parar de sobrecarregar os acessórios , porque às vezes dependemos muito neles quando não é realmente necessário e isso torna quase o mesmo como se publicássemos as variáveis.
fonte
Obrigado, isso realmente esclareceu meu pensamento. Agora, aqui estão (quase) 10 (quase) boas razões para NÃO usar getters e setters:
Os três últimos que eu estou saindo (N / A ou D / C) ...
fonte
Eu sei que é um pouco tarde, mas acho que há algumas pessoas interessadas em desempenho.
Eu fiz um pequeno teste de desempenho. Eu escrevi uma classe "NumberHolder" que, bem, contém um número inteiro. Você pode ler esse número inteiro usando o método getter
anInstance.getNumber()
ou acessando diretamente o número usandoanInstance.number
. Meu programa lê o número 1.000.000.000 de vezes, nos dois sentidos. Esse processo é repetido cinco vezes e a hora é impressa. Eu tenho o seguinte resultado:(O tempo 1 é o caminho direto, o tempo 2 é o getter)
Veja bem, o getter é (quase) sempre um pouco mais rápido. Então eu tentei com diferentes números de ciclos. Em vez de 1 milhão, usei 10 e 0,1 milhões. Os resultados:
10 milhões de ciclos:
Com 10 milhões de ciclos, os tempos são quase os mesmos. Aqui estão 100 mil (0,1 milhões) ciclos:
Também com diferentes quantidades de ciclos, o getter é um pouco mais rápido que o normal. Espero que isso tenha ajudado.
fonte
Não use setters getters, a menos que seja necessário para sua entrega atual. Ou seja, não pense muito no que aconteceria no futuro, se alguma coisa a ser alterada for uma solicitação de mudança na maioria dos aplicativos de produção, sistemas.
Pense simples, fácil e adicione complexidade quando necessário.
Eu não tiraria proveito da ignorância dos proprietários de empresas com profundo conhecimento técnico, apenas porque acho correto ou gosto da abordagem.
Eu tenho um sistema massivo escrito sem setters de getters apenas com modificadores de acesso e alguns métodos para validar e executar a lógica de negócios. Se você absolutamente precisava do. Use qualquer coisa.
fonte
Usamos getters e setters:
Os métodos Getter e setter são interfaces públicas para acessar membros da classe privada.
Mantra de encapsulamento
O mantra de encapsulamento é tornar os campos privados e os métodos públicos.
Mesmo que os métodos getter e setter não adicionem novas funcionalidades, podemos mudar de idéia mais tarde para criar esse método
Em qualquer lugar que um valor possa ser usado, um método que retorne esse valor pode ser adicionado. Ao invés de:
usar
Em termos leigos
Suponha que precisamos armazenar os detalhes disso
Person
. EstePerson
tem os camposname
,age
esex
. Fazer isso envolve a criação de métodos paraname
,age
esex
. Agora, se nós precisamos criar uma outra pessoa, torna-se necessário criar os métodos paraname
,age
,sex
tudo de novo.Em vez de fazer isso, podemos criar um bean
class(Person)
com os métodos getter e setter. Portanto, amanhã podemos criar objetos desse Beanclass(Person class)
sempre que precisarmos adicionar uma nova pessoa (veja a figura). Portanto, estamos reutilizando os campos e métodos da classe bean, o que é muito melhor.fonte
Passei um bom tempo pensando sobre o caso Java e acredito que os verdadeiros motivos são:
Em outras palavras, a única maneira de especificar um campo em uma interface é fornecendo um método para escrever um novo valor e um método para ler o valor atual.
Esses métodos são os infames getter e setter ....
fonte
Pode ser útil para carregamento lento. Digamos que o objeto em questão esteja armazenado em um banco de dados e você não deseja obtê-lo, a menos que precise. Se o objeto for recuperado por um getter, o objeto interno poderá ser nulo até que alguém o solicite; você poderá obtê-lo na primeira chamada para o getter.
Eu tinha uma classe de página base em um projeto que foi entregue a mim e estava carregando alguns dados de algumas chamadas de serviço web diferentes, mas os dados nessas chamadas de serviço web nem sempre eram usados em todas as páginas filho. Os serviços da Web, por todos os benefícios, são pioneiros em novas definições de "lento", para que você não queira fazer uma chamada de serviço da Web se não for necessário.
Mudei de campos públicos para getters, e agora os getters verificam o cache e, se ele não estiver lá, chame o serviço da web. Portanto, com um pequeno agrupamento, muitas chamadas de serviço da Web foram impedidas.
Portanto, o getter me impede de tentar descobrir, em cada página filha, o que vou precisar. Se eu precisar, ligo para o getter, e ele vai encontrá-lo para mim, se ainda não o tiver.
fonte
Um aspecto que eu perdi nas respostas até agora, a especificação de acesso:
fonte
Edição: Eu respondi a essa pergunta porque há um monte de gente aprendendo programação perguntando isso, e a maioria das respostas é muito tecnicamente competente, mas não é tão fácil de entender se você é um novato. Éramos todos novatos, então pensei em tentar uma resposta mais amigável para iniciantes.
Os dois principais são polimorfismo e validação. Mesmo que seja apenas uma estrutura de dados estúpida.
Digamos que temos essa classe simples:
Uma classe muito simples que contém a quantidade de líquido nela e qual é sua capacidade (em mililitros).
O que acontece quando eu faço:
Bem, você não esperaria que isso funcionasse, certo? Você quer que haja algum tipo de verificação de sanidade. E pior, e se eu nunca especificasse a capacidade máxima? Oh querida, nós temos um problema.
Mas há outro problema também. E se as garrafas fossem apenas um tipo de recipiente? E se tivéssemos vários recipientes, todos com capacidades e quantidades de líquido cheias? Se pudéssemos fazer uma interface, deixamos o resto do nosso programa aceitar essa interface, e garrafas, bidão e todo tipo de coisa funcionariam de maneira intercambiável. Isso não seria melhor? Como as interfaces exigem métodos, isso também é uma coisa boa.
Nós acabaríamos com algo como:
Ótimo! E agora apenas mudamos o Bottle para isso:
Vou deixar a definição de BottleOverflowException como um exercício para o leitor.
Agora observe como isso é mais robusto. Agora podemos lidar com qualquer tipo de contêiner em nosso código aceitando LiquidContainer em vez de Bottle. E como essas garrafas lidam com esse tipo de coisa pode ser diferente. Você pode ter garrafas que gravam seu estado no disco quando elas são alteradas ou garrafas que salvam em bancos de dados SQL ou o GNU sabe o que mais.
E tudo isso pode ter maneiras diferentes de lidar com várias gritos. O Bottle apenas verifica e se está transbordando lança uma RuntimeException. Mas isso pode ser a coisa errada a se fazer. (Existe uma discussão útil sobre o tratamento de erros, mas eu estou mantendo isso muito simples aqui de propósito. As pessoas nos comentários provavelmente apontarão as falhas dessa abordagem simplista.;)
E sim, parece que passamos de uma idéia muito simples para obter respostas muito melhores rapidamente.
Observe também que você não pode alterar a capacidade de uma garrafa. Agora está gravado em pedra. Você pode fazer isso com um int declarando-o final. Mas se essa fosse uma lista, você poderia esvaziá-la, adicionar coisas novas e assim por diante. Você não pode limitar o acesso a tocar as entranhas.
Há também a terceira coisa que nem todos abordaram: getters e setters usam chamadas de método. Isso significa que eles se parecem com métodos normais em qualquer outro lugar. Em vez de ter uma sintaxe específica estranha para DTOs e outras coisas, você tem a mesma coisa em todos os lugares.
fonte
Em idiomas que não suportam "propriedades" (C ++, Java) ou exigem recompilação de clientes ao alterar campos para propriedades (C #), é mais fácil modificar os métodos get / set. Por exemplo, adicionar lógica de validação a um método setFoo não exigirá alteração da interface pública de uma classe.
Em idiomas que suportam propriedades "reais" (Python, Ruby, talvez Smalltalk?), Não há sentido em obter / definir métodos.
fonte
Um dos princípios básicos do design de OO: encapsulamento!
Oferece muitos benefícios, um dos quais é possível alterar a implementação do getter / setter nos bastidores, mas qualquer consumidor desse valor continuará a funcionar enquanto o tipo de dados permanecer o mesmo.
fonte
Você deve usar getters e setters quando:
Portanto, raramente é uma questão geral de OO; é uma pergunta específica de idioma, com respostas diferentes para idiomas diferentes (e diferentes casos de uso).
Do ponto de vista da teoria do OO, getters e setters são inúteis. A interface da sua classe é o que ela faz, não o seu estado. (Caso contrário, você escreveu a classe errada.) Em casos muito simples, onde o que uma classe faz é apenas, por exemplo, representar um ponto em coordenadas retangulares, * os atributos fazem parte da interface; getters e setters apenas obscurecem isso. Mas, em qualquer coisa, exceto em casos muito simples, nem os atributos, nem os getters e setters fazem parte da interface.
Dito de outra forma: se você acredita que os consumidores de sua classe nem deveriam saber que você tem um
spam
atributo, muito menos poder alterá-lo à vontade, então dar a eles umset_spam
método é a última coisa que você deseja fazer.* Mesmo para essa classe simples, talvez você não queira permitir a definição dos valores
x
ey
. Se isso é realmente uma classe, não deveria ter métodos comotranslate
,rotate
, etc.? Se é apenas uma aula porque seu idioma não possui registros / estruturas / tuplas nomeadas, isso não é realmente uma questão de OO…Mas ninguém nunca faz o projeto geral de OO. Eles estão fazendo design e implementação em um idioma específico. E em alguns idiomas, getters e setters estão longe de serem inúteis.
Se o seu idioma não tiver propriedades, a única maneira de representar algo que é conceitualmente um atributo, mas na verdade é computado, ou validado etc. é através de getters e setters.
Mesmo que seu idioma tenha propriedades, pode haver casos em que sejam insuficientes ou inapropriados. Por exemplo, se você deseja permitir que as subclasses controlem a semântica de um atributo, em idiomas sem acesso dinâmico, uma subclasse não poderá substituir uma propriedade computada por um atributo.
Quanto ao "e se eu quiser alterar minha implementação mais tarde?" question (que é repetido várias vezes com palavras diferentes na pergunta do OP e na resposta aceita): Se realmente é uma alteração pura na implementação e você começou com um atributo, pode alterá-lo para uma propriedade sem afetar a interface. A menos, é claro, que seu idioma não suporte isso. Portanto, esse é realmente o mesmo caso novamente.
Além disso, é importante seguir os idiomas da linguagem (ou estrutura) que você está usando. Se você escrever um belo código no estilo Ruby em C #, qualquer desenvolvedor experiente em C # que não seja você terá problemas para lê-lo, e isso é ruim. Algumas linguagens têm culturas mais fortes em torno de suas convenções do que outras. - e pode não ser coincidência que Java e Python, que estão em extremos opostos do espectro de como são os geters idiomáticos, possuam duas das culturas mais fortes.
Além dos leitores humanos, haverá bibliotecas e ferramentas que esperam que você siga as convenções e torne sua vida mais difícil se não o fizer. Conectar os widgets do Interface Builder a qualquer coisa, exceto propriedades ObjC, ou usar determinadas bibliotecas de simulação Java sem getters, está apenas dificultando sua vida. Se as ferramentas são importantes para você, não lute contra elas.
fonte
Do ponto de vista do design da orientação a objeto, ambas as alternativas podem ser prejudiciais à manutenção do código, enfraquecendo o encapsulamento das classes. Para uma discussão, você pode consultar este excelente artigo: http://typicalprogrammer.com/?p=23
fonte
Os métodos getter e setter são métodos acessadores, o que significa que geralmente são uma interface pública para alterar membros da classe privada. Você usa métodos getter e setter para definir uma propriedade. Você acessa os métodos getter e setter como propriedades fora da classe, mesmo que os defina dentro da classe como métodos. Essas propriedades fora da classe podem ter um nome diferente do nome da propriedade na classe.
Existem algumas vantagens em usar métodos getter e setter, como a capacidade de permitir a criação de membros com funcionalidades sofisticadas que você pode acessar como propriedades. Eles também permitem criar propriedades somente leitura e somente gravação.
Embora os métodos getter e setter sejam úteis, você deve tomar cuidado para não usá-los demais, pois, entre outros problemas, eles podem dificultar a manutenção do código em determinadas situações. Além disso, eles fornecem acesso à sua implementação de classe, como membros públicos. A prática de POO desencoraja o acesso direto às propriedades dentro de uma classe.
Ao escrever classes, você sempre é incentivado a tornar privadas o máximo possível de suas variáveis de instância e adicionar métodos getter e setter adequadamente. Isso ocorre porque há várias vezes em que você não deseja permitir que os usuários alterem determinadas variáveis nas suas classes. Por exemplo, se você possui um método estático privado que rastreia o número de instâncias criadas para uma classe específica, não deseja que um usuário modifique esse contador usando o código. Somente a declaração do construtor deve incrementar essa variável sempre que for chamada. Nessa situação, você pode criar uma variável de instância privada e permitir um método getter apenas para a variável counter, o que significa que os usuários podem recuperar o valor atual apenas usando o método getter e não poderão definir novos valores usando o método setter.
fonte
Código evolui .
private
é ótimo para quando você precisa de proteção de membro de dados . Eventualmente, todas as classes devem ser uma espécie de "miniprogramas" que possuem uma interface bem definida, da qual você não pode se ferrar com os elementos internos .Dito isso, o desenvolvimento de software não é sobre definir a versão final da classe como se você estivesse pressionando alguma estátua de ferro fundido na primeira tentativa. Enquanto você trabalha com ele, o código é mais parecido com o barro. Ele evolui à medida que você o desenvolve e aprende mais sobre o domínio do problema que está resolvendo. Durante o desenvolvimento, as classes podem interagir umas com as outras do que deveriam (dependência que você planeja levar em consideração), fundir-se ou separar-se. Então eu acho que o debate se resume a pessoas que não querem escrever religiosamente
Então você tem:
Ao invés de
Não é apenas
getVar()
visualmente barulhento, como também dá a ilusão de quegettingVar()
é um processo mais complexo do que realmente é. Como você (como redator da turma) considera a santidadevar
é particularmente confuso para um usuário da sua turma se ela tiver um setstars - então parece que você está colocando esses portões para "proteger" algo que você insiste que é valioso, (a santidade devar
), mas mesmo assim você concedevar
a proteção não vale muito pela capacidade de alguém simplesmente entrar eset
var
com o valor que quiser, sem que você sequer espreite o que está fazendo.Então, programo da seguinte maneira (assumindo uma abordagem do tipo "ágil" - ou seja, quando escrevo código sem saber exatamente o que estará fazendo / não tenho tempo ou experiência para planejar um conjunto elaborado de interface em estilo cascata):
1) Comece com todos os membros públicos para objetos básicos com dados e comportamento. É por isso que em todo o meu código de "exemplo" em C ++ você notará que eu estou usando, e
struct
não emclass
qualquer lugar.2) Quando o comportamento interno de um objeto para um membro de dados se torna complexo o suficiente (por exemplo, ele gosta de manter um interno
std::list
em algum tipo de ordem), as funções do tipo acessador são gravadas. Como estou programando sozinho, nem sempre defino o membroprivate
imediatamente, mas em algum momento da evolução da classe o membro será "promovido" para umprotected
ou outroprivate
.3) As classes que são totalmente desenvolvidas e têm regras estritas sobre seus internos (ou seja, elas sabem exatamente o que estão fazendo e você não deve "foder" (termo técnico) com seus internos) recebem a
class
designação de membros particulares padrão, e apenas alguns membros selecionados podem participarpublic
.Acho que essa abordagem me permite evitar ficar sentado e escrever religiosamente getter / setters quando muitos membros de dados são migrados, trocados etc. durante os estágios iniciais da evolução de uma classe.
fonte
Há um bom motivo para considerar o uso de acessadores: não há herança de propriedade. Veja o próximo exemplo:
Resultado:
fonte
Getters e setters são usados para implementar dois dos aspectos fundamentais da Programação Orientada a Objetos, que são:
Suponha que tenhamos uma classe Employee:
Aqui, os detalhes da implementação do Nome completo estão ocultos do usuário e não podem ser acessados diretamente, ao contrário de um atributo público.
fonte
Um outro uso (em idiomas que suportam propriedades) é que setters e getters podem sugerir que uma operação não é trivial. Normalmente, você deseja evitar fazer algo que seja computacionalmente caro em uma propriedade.
fonte
execute
ou o carobuild
.Uma vantagem relativamente moderna dos getters / setters é que facilita a navegação no código nos editores de código com tags (indexados). Por exemplo, se você quiser ver quem define um membro, pode abrir a hierarquia de chamadas do configurador.
Por outro lado, se o membro é público, as ferramentas não permitem filtrar o acesso de leitura / gravação ao membro. Então você tem que percorrer todos os usos do membro.
fonte
Em uma linguagem orientada a objetos, os métodos e seus modificadores de acesso declaram a interface para esse objeto. Entre o construtor e os métodos acessador e mutador, é possível ao desenvolvedor controlar o acesso ao estado interno de um objeto. Se as variáveis forem simplesmente declaradas públicas, não há como regular esse acesso. E quando estamos usando setters, podemos restringir o usuário para a entrada de que precisamos. Significa que o feed dessa variável passará por um canal adequado e o canal é predefinido por nós. Portanto, é mais seguro usar setters.
fonte
Além disso, isso é para "proteger o futuro" da sua turma. Em particular, mudar de um campo para uma propriedade é uma quebra da ABI; portanto, se você decidir mais tarde que precisa de mais lógica do que apenas "definir / obter o campo", precisará interromper a ABI, o que obviamente cria problemas para qualquer coisa mais já compilado contra sua classe.
fonte
Gostaria apenas de lançar a ideia da anotação: @getter e @setter. Com @getter, você poderá obj = class.field, mas não class.field = obj. Com o @setter, vice-versa. Com @getter e @setter, você poderá fazer as duas coisas. Isso preservaria o encapsulamento e reduziria o tempo ao não chamar métodos triviais em tempo de execução.
fonte