Todas as suas variáveis precisam ser declaradas privadas? [duplicado]

14

Sei que é uma prática recomendada permanecer seguro e que sempre devemos impedir que outras pessoas acessem diretamente as propriedades de uma classe. Eu ouço isso o tempo todo de professores universitários, e também vejo isso o tempo todo em muitos códigos-fonte lançados no App Hub . De fato, os professores dizem que eles realmente tiram marcas para cada variável que é declarada pública.

Agora, isso me deixa sempre declarando variáveis como privadas. Não importa o que. Mesmo se cada uma dessas variáveis tivesse um getter e um setter.

Mas aqui está o problema: é um trabalho tedioso. Eu costumo perder rapidamente o interesse em um projeto toda vez que preciso ter uma variável em uma classe que poderia simplesmente ter sido declarada pública em vez de privada com um getter e um setter.

Então, minha pergunta é: preciso realmente declarar todas minhas variáveis como particulares? Ou posso declarar algumas variáveis públicas sempre que elas exigem um getter e um setter?

    
por skizeey 13.03.2011 / 09:24
fonte

10 respostas

19

Professores dizendo "SEMPRE façam isto ou aquilo" em relação à programação devem ser demitidos, ou voltar para a escola. Na programação, nunca existe uma única maneira de fazer alguma coisa, tudo depende da aplicação específica.

Exemplo para o seu caso: suponha que você tenha uma classe representando uma estrutura de configuração simples com 10 campos, mas nenhuma funcionalidade real, portanto, nenhum método, exceto um construtor, talvez. Todos os membros podem ser lidos / escritos. Pessoalmente eu preferiria

class MyConfig
{
public:
  int a;
  int b;
  int c;
  int d;
  int e;
};

muito, muito mais do que o próximo, que também não adiciona nenhuma funcionalidade extra ao original.

class MyConfig
{
public:
  int GetA() const{ return a; }
  void SetA( int i ){ a = i; }
  int GetB() const{ return b; }
  void SetB( int i ){ b = i; }
//you get the point.. 
private:
  int a;
  int b;
  int c;
  int d;
  int e;
};
    
por 13.03.2011 / 09:54
fonte
27

Em geral, sim, eu e muitos outros fazemos exceções para o DTO ver este post de blog tio Bob Martin.

Se tudo o que você está fazendo é criar variáveis privadas e usar getters e setters, você pode pensar em por que está fazendo isso? Há muitas pessoas que dizem que getters e setters são maus, veja este artigo ou este artigo de Alan Holub. A partir desse artigo:

Summing up

Let's pull everything together: You shouldn't use accessor methods (getters and setters) unless absolutely necessary because these methods expose information about how a class is implemented and as a consequence make your code harder to maintain. Sometimes get/set methods are unavoidable, but an experienced OO designer could probably eliminate 99 percent of the accessors currently in your code without much difficulty.

Getter/setter methods often make their way in code because the coder was thinking procedurally. The best way to break out of that procedural mindset is to think in terms of a conversation between objects that have well-defined responsibilities. Cunningham's CRC card approach is a great way to get started.

    
por 13.03.2011 / 09:51
fonte
9

Há uma boa razão para usar getters e setters em Java em vez de ter campos públicos.

A razão é porque você deve sempre codificar para interfaces e interfaces não permitem especificar campos, mas apenas métodos.

    
por 13.03.2011 / 10:49
fonte
3

Java, diferentemente de outras linguagens como Ruby, diferencia entre acesso direto a uma propriedade e acessa uma propriedade por meio de acessadores / mutadores. Uma boa prática orientada a objetos diz que você deve, sempre que possível, ocultar o estado interno de um objeto do lado de fora. Ou seja, a representação interna dos dados não deve ser manipulada diretamente por objetos externos. A razão é que você poderia aplicar alguma lógica ao valor antes de a ação ser levada (ou seja: validar, limpar uma string, formatar o retorno, ...). O problema é que a maioria das pessoas pensa que "POJO" deve ser "o mais limpo possível", e acabam implementando essas validações / formatações / limpeza em outros lugares, deixando os POJOs mudos e tediosos para escrever.

Dito isso, recentemente vi uma biblioteca chamada "lombok", que me permite escrever apenas as propriedades e gerar os getters / setters na hora. Se eu precisar fazer alguma lógica extra em qualquer acessador / mutador, eu apenas farei a implementação real para ele e o lombok irá ignorar esse método específico.

    
por 13.03.2011 / 11:20
fonte
3

Como você mesmo diz:

But here's the problem: it's tedious work.[emphasis mine] I tend to quickly loose interest in a project every time I need to have a variable in a class that could have simply been declared public instead of private with a getter and a setter.

Você está contornando o trabalho tedioso ao tentar argumentar que a sua necessidade está fora de existência, em vez de torná-lo menos tedioso, o que basicamente significa trabalhar em torno do problema em vez de resolvê-lo. Para resolvê-lo:

Use as ferramentas certas e use-as corretamente

Se criar acessores simples for muito trabalhoso, seu conjunto de ferramentas atual precisa ser melhorado.
De fato, sempre que houver algum trabalho tedioso, seu conjunto de ferramentas precisa ser melhorado .

Para muitos idiomas, há algum tipo de açúcar sintático disponível para criar acessadores ou você pode usar pré-processadores para isso e a maioria dos IDEs fornece trechos de código / geradores de código. Na verdade, em qualquer IDE decente, é uma questão de um pressionamento de tecla converter um campo público em um privado com acessores.

Eu poderia fornecer uma explicação bastante longa sobre por que usar campos públicos viola completamente a OOP. Ao mesmo tempo, OOP não é a verdade suprema e às vezes é melhor escolher conscientemente uma alternativa, se você sabe o que está fazendo e as circunstâncias estão certas. Então, sim, há casos em que o uso de campos públicos simples é ok.
No entanto, isso não é o caso, porque você não está tomando essa decisão com base em qualquer tipo de restrição técnica, mas apenas porque seu fluxo de trabalho precisa de otimização.

    
por 08.02.2012 / 16:40
fonte
1

Expor membros, seja como campos públicos ou através de simples getters e setters, vai contra o idéias originais de OO .

Se você estiver modelando valores e não objetos, poderá haver motivos para modelá-los como valores.

Objetos falando puramente são sobre o comportamento de qualquer variável membro é um detalhe de implementação e nenhum valor é parte do comportamento. Então, se você deseja fazer OO purista toda vez que quiser criar um setter ou getter, você deve fazer suas próprias perguntas sobre seu design, já que a necessidade de getters e setters (quando não estão falando sobre valores como opostos a objetos) é um cheiro que você não está modelando o que o sistema faz (comportamento), mas o que é (dados). Um paradigma que enfoca a separação desses conceitos é o DCI

    
por 08.02.2012 / 15:07
fonte
0

Sempre é uma palavra muito strong e eu a evitarei. Se é apenas uma questão de digitação, quais são as macros de teclado. Escreva um script pequeno que levará um preenchimento de fonte java e encontre todos os vars públicos para convertê-los em privados e escreva os getters e setters para você.

Eu acho que é sempre uma boa idéia automatizar as partes da placa chata e de caldeira do trabalho. Melhora a qualidade do código porque o material chato é feito pelo computador.

Lembre-se do seguinte:

  1. O código-fonte é apenas dados

  2. Os programas manipulam dados

  3. Escreva um programa para manipular seus dados de maneiras úteis!

Boa sorte!

    
por 13.03.2011 / 10:59
fonte
0

O ponto com getters / setters vs. variáveis públicas é a separação de interesses. As variáveis internas são um detalhe de implementação de uma classe e, portanto, não devem ser vistas de fora.

O que deve ser visível de fora são as propriedades que são manipuladas pela classe, e essas propriedades podem não ter uma correspondência um para um com variáveis internas.

Por exemplo, uma classe pode manipular uma propriedade 'temperature'. Uma variável interna pode estar ligada a esta temperatura, mas os usuários não devem assumir o que representa o valor armazenado naquela variável: ° C, ° F, ° K, ou mesmo, dependendo do sensor, medida bruta expressa em: mm, V ...

Os getters e setters devem aplicar-se a propriedades, não a variáveis internas, permitindo assim a inclusão de funções de calibração ou conversão.

Dessa forma, internals de classe podem mudar sem atualizar sua interface e todos os outros componentes dependendo da classe.

    
por 08.02.2012 / 15:05
fonte
0

Depois de ler algumas respostas, meu primeiro ponto seria que, nesse contexto, eu não acredito que deva ser o mesmo que dizer must que não é o mesmo que dizer > tenho que , eu acho que você talvez esteja enfatizando sempre .

  • deve implica que este é um consenso generalizado de que esta é uma abordagem melhor ou mais adequada
    • você deve sempre declarar seus membros como privados
  • must implica que esta é a forma como é feito
    • você deve sempre declarar seus membros como privados
  • tem que implica em nenhuma outra opção
    • você precisa sempre declarar seus membros como privados
De fato, em todos os três exemplos (particularmente dada a circunstância da qual esta questão derivava), um e a OMI deveriam (embora nenhum deles devesse ou devesse) consultar qualquer afirmação feita a eles, é assim que você programa o melhor computador de todos. Por exemplo, se alguém disser que você deve sempre fazer alguma coisa, apesar do fato de que você sabe que, dessa vez, isso seria prejudicial se você fizesse isso sem questionar a racionalidade deles?

Eu imagino que neste caso o seu tutor (muito provavelmente por facilidade) tenha pensado em você, uma prática melhor com a qual eu (e talvez muitos outros) concordaria. A questão que eu sinto nunca deve ser por que tornar um membro privado, mas na verdade o inverso de por que torná-lo público, tomando como exemplo o facebook, as pessoas claramente gostam de divulgar informações sobre si mesmos, mas mesmo assim meus amigos podem ver isso , minha família pode ver isso, e você que eu não conheço não consegue ver nada.

Trazendo isso de volta para OOP e, em particular, Java, uma das principais razões para getters e setters é IMO (e posso estar errado) um caso de boa prática semântica, você obj.getState() e obj.setState() em oposição a obj.state e obj.state = 'foo' , em ambos os casos eu argumentaria que o processo de fazer isso é imperativo. Eu gostaria de pensar que a orientação a objetos não é apenas romper com esse paradigma, mas entre outros, encapsulando dados e funções em um componente reutilizável. Se não ocultamos nada, acabamos com algum namespace para armazenar dados e métodos?

Outro ponto-chave que acredito se resume à substituição, as classes herdadas de uma superclasse contendo variáveis públicas agora estão presas a uma variável pública que, para mim, parece que isso pode levar a uma diminuição na reutilização. Usando getters e setters, você forneceu uma maneira de subclasses substituir o acesso a suas variáveis, talvez adicionar aquele bit de validação com o qual você nunca se incomodou.

Quanto a ser tedioso sobre escrever getters e setters, isso é realmente nulo e vazio, pois acho que a maioria dos IDE fará muito disso para você (e como eu acabei de encontrar o lombok que parece muito legal e me lembra @property etc no objetivo-c)

Em suma, sim, você deve sempre usar membros privados, a menos que você tenha uma boa razão para não fazê-lo (as DTOs seriam, até certo ponto, uma exceção razoável)

    
por 08.02.2012 / 17:06
fonte
-2

A razão pela qual você sempre tem que implementar getters e setters é porque todo mundo diz para você (as pessoas sãs chamam isso de Dogma). Nos 10 anos em que eu programo o Java, provavelmente 99% das propriedades que usei estão disponíveis publicamente através de getters e setters, portanto, na prática, elas são públicas. Nós facilitamos a exceção, em vez da regra.

    
por 08.02.2012 / 14:35
fonte