Prefere membros da classe ou passa argumentos entre métodos internos?

39

Suponha que dentro da parte privada de uma classe exista um valor que seja utilizado por vários métodos privados. As pessoas preferem ter isso definido como uma variável de membro para a classe ou passá-lo como argumento para cada um dos métodos - e por quê?

Por um lado, pude argumentar que reduzir o estado (ou seja, variáveis-membro) em uma classe é geralmente uma coisa boa, embora se o mesmo valor esteja sendo usado repetidamente nos métodos de uma classe, parece que isso seria um ideal candidato a representação como estado da classe para tornar o código visivelmente mais limpo, se nada mais.

Editar:

Para esclarecer alguns dos comentários / perguntas que foram levantados, não estou falando de constantes e isso não está relacionado a nenhum caso específico, mas apenas a uma hipótese de que eu estava falando com outras pessoas.

Ignorando o ângulo de POO por um momento, o caso de uso específico que eu tinha em mente era o seguinte (assuma a referência por referência apenas para tornar o pseudocódigo mais limpo)

int x
doSomething(x)
doAnotherThing(x)
doYetAnotherThing(x)
doSomethingElse(x)

Então, o que eu quero dizer é que há alguma variável comum entre várias funções - no caso que eu tinha em mente, era devido ao encadeamento de funções menores. Em um sistema OOP, se esses fossem todos os métodos de uma classe (digamos, devido à refatoração através da extração de métodos de um método grande), essa variável poderia ser passada em torno de todos eles ou poderia ser um membro da classe.

geoffjentry
fonte
1
Como esse valor é usado? É constante? Isso muda? Está sujeito a alterações entre compilações?
Oded
Quando as coisas são automaticamente determinadas como iguais, é mais fácil pensar que isso não importa. E se você tivesse uma função que precisasse de um valor ajustado (x) como x-1?
Jeffo

Respostas:

15

Se o valor for uma propriedade da classe, mantenha-o na classe, caso contrário, mantenha-o fora. Você não cria seus métodos de classe primeiro, você cria suas propriedades primeiro. Se você não pensou em colocar essa propriedade dentro da classe, provavelmente há uma razão para isso.

A pior coisa que você pode fazer, em termos de escalabilidade, é alterar seu código por conveniência. Mais cedo ou mais tarde, você verá que seu código está cheio e duplicado. No entanto, devo admitir que às vezes eu quebro essa regra ... A conveniência é tão atraente.

AJC
fonte
1
Eu concordo - o design / objetivo original da classe deve informar se deve ser uma variável de membro ou um argumento. Também vale a pena pensar no ângulo de injeção de dependência.
Martijn Verburg
14

Se você realmente não precisa manter o estado entre invocações (e aparentemente não, ou não faria a pergunta), eu preferiria que o valor fosse um argumento, e não uma variável de membro, porque uma rápida olhada na assinatura do método diz que ele usa o argumento, embora seja um pouco mais difícil dizer imediatamente quais variáveis ​​de membro são usadas pelo método. Também nem sempre é rápido determinar para que servem as variáveis ​​de membro privado.

Portanto, normalmente eu não concordaria que o código usando variáveis-membro é visivelmente mais limpo, mas se as assinaturas do método estiverem ficando fora de controle, eu poderia fazer uma exceção. É uma pergunta que vale a pena, mas não é algo em que o projeto se apoiará.

psr
fonte
10

Obrigado por fazer a pergunta, eu também queria fazer isso.

Quando eu estava pensando sobre isso, há algumas vantagens em por que passar isso como argumento

  • é mais fácil testar -> mais fácil de manter (relacionado ao último ponto)
  • não tem efeitos colaterais
  • é mais fácil entender

Vejo claramente seu ponto de vista, por exemplo: um é analisar o documento do Excel (usando a biblioteca POI, por exemplo) e, em vez de passar a instância da linha para todos os métodos que precisam trabalhar com essa linha, o autor possui uma variável de membro currentRowe trabalha com ela.

Eu diria que deveria haver um nome para esse anti-padrão, não é? (não listado aqui )

Betlista
fonte
Qual anti-padrão você quer dizer?
Vahid Ghadiri 29/10
Em suma, para ter variável de membro apenas para parâmetro share entre dois (ou mais) chamadas de função ...
Betlista
1

Talvez você deva extrair uma nova classe contendo todos os métodos que compartilham esse valor. Obviamente, o método de nível mais alto será público na nova classe. Pode ser útil expor esse método para teste.

Se você tem dois ou mais temporários que são sempre passados ​​juntos, quase certamente você deve extrair uma nova classe.

Kevin Cline
fonte
1

As pessoas preferem ter isso definido como uma variável de membro para a classe ou passá-lo como argumento para cada um dos métodos - e por quê?

Se eu entendo o que você está perguntando: Os métodos em uma classe são, por definição, a par dos detalhes da implementação, portanto, não tenho dúvidas quanto ao uso de qualquer membro diretamente de qualquer método.

Por um lado, pude ver um argumento a ser feito de que reduzir o estado (ou seja, variáveis ​​de membro) em uma classe geralmente é uma coisa boa ...

Não há nada errado em declarar a private static finalpara definir constantes. O compilador poderá usar o valor considerando algumas otimizações e, sendo constantes, elas realmente não adicionam estado à classe.

embora se o mesmo valor estiver sendo usado repetidamente nos métodos de uma classe ...

Ser capaz de se referir a ele simbolicamente (por exemplo, BLRFL_DURATION) e não precisar adicionar argumentos extras aos seus métodos tornará seu código mais legível e, portanto, mais sustentável.

Blrfl
fonte
0

se o valor não mudar, é por definição uma constante e deve ser encapsulado dentro da classe. Nesse caso, não é considerado que afete o estado de um objeto. Não conheço o seu caso, mas penso em algo como PI na trigonometria. Se você tentar passar um argumento dessa constante, poderá expor o resultado a erro se o cliente transmitir o valor errado ou um valor que não seja da mesma precisão que o (s) método (s) espera (s).

NoChance
fonte