Quando usar uma variável de instância de objeto versus passar um argumento para o método

93

Como você decide entre passar argumentos para um método ou simplesmente declará-los como variáveis ​​de instância de objeto que são visíveis para todos os métodos do objeto?

Eu prefiro manter as variáveis ​​de instância em uma lista no final da classe, mas essa lista fica mais longa à medida que meu programa cresce. Eu acho que se uma variável é passada com frequência suficiente, ela deve ser visível para todos os métodos que precisam dela, mas então eu me pergunto, "se tudo for público, não haverá necessidade de passar nada!"

Ziggy
fonte
1
Se você tiver exemplos específicos, poderá obter respostas mais úteis diretamente
brabster

Respostas:

55

Já que você está se referindo a variáveis ​​de instância, estou supondo que você está trabalhando em uma linguagem orientada a objetos. Até certo ponto, quando usar variáveis ​​de instância, como definir seu escopo e quando usar variáveis ​​locais é subjetivo, mas existem algumas regras básicas que você pode seguir sempre que criar suas classes.

  • Variáveis ​​de instância são normalmente consideradas atributos de uma classe. Pense neles como adjetivos do objeto que será criado a partir de sua classe. Se seus dados de instância podem ser usados ​​para ajudar a descrever o objeto, então provavelmente é seguro apostar que é uma boa escolha para dados de instância.

  • Variáveis ​​locais são usadas dentro do escopo dos métodos para ajudá-los a completar seu trabalho. Normalmente, um método deve ter o propósito de obter alguns dados, retornar alguns dados e / ou processar / executar um algoritmo em alguns dados. Às vezes, ajuda pensar em variáveis ​​locais como formas de ajudar um método a ir do começo ao fim.

  • O escopo da variável de instância não é apenas para segurança, mas também para encapsulamento. Não presuma que o "objetivo deve ser manter todas as variáveis ​​privadas." Em casos de herança, tornar as variáveis ​​protegidas geralmente é uma boa alternativa. Em vez de marcar todos os dados da instância como públicos, você cria getters / setters para aqueles que precisam ser acessados ​​para o mundo externo. Não disponibilize todos - apenas os de que você precisa. Isso acontecerá em todo o ciclo de vida do desenvolvimento - é difícil adivinhar desde o início.

Quando se trata de passar dados em uma classe, é difícil dizer que o que você está fazendo é uma boa prática sem ver algum código. Às vezes, operar diretamente nos dados da instância é bom; outras vezes, não é. Em minha opinião, isso é algo que vem com a experiência - você desenvolverá alguma intuição conforme suas habilidades de pensamento orientado a objetos melhoram.

Tom
fonte
Minha resposta seria adicionar esta resposta à resposta H-Man2 (tempo de vida). Deve ser um atributo de membro se e somente se for um estado persistente do objeto. Ou seja, o valor faz sentido por si só fora do escopo da pilha de métodos atual.
David Rodríguez - dribeas
Minha reação instintiva é concordar com David e H-MAn2. No entanto, estou lendo "código limpo" de Robert c Martin e no capítulo 3 ele refatora o código para mover algo de um parâmetro de método para uma variável de membro, porque ter muitos parâmetros é ruim. No balanço, acho que se sua classe tem apenas uma única responsabilidade, então o tempo de vida do objeto é o mesmo que o tempo de vida dessa computação, então talvez a resposta real seja que se você tiver que fazer esta pergunta, então sua classe é muito grande?
Andy
@ DavidRodríguez-dribeas o que você quer dizer com pilha de métodos?
comprometeu-se
@committedandroider: se o valor sobreviver à chamada de função atual
David Rodríguez - dribeas
46

Principalmente, isso depende do tempo de vida dos dados que você armazena na variável. Se os dados forem usados ​​apenas durante um cálculo, passe-os como um parâmetro. Se os dados estiverem limitados ao tempo de vida do objeto, use uma variável de instância.

Quando sua lista de variáveis ​​ficar muito longa, talvez seja um bom ponto para pensar em refatorar algumas partes da classe em uma nova classe.

H-Man2
fonte
21

Na minha opinião, as variáveis ​​de instância são necessárias apenas quando os dados serão usados ​​nas chamadas.

Aqui está um exemplo:

myCircle = myDrawing.drawCircle(center, radius);

Agora vamos criar imagens da classe myDrawing usando 15 funções auxiliares para criar o objeto myCircle e cada uma dessas funções precisará do centro e do raio. Eles ainda não devem ser definidos como variáveis ​​de instância da classe myDrawing. Porque eles nunca mais serão necessários.

Por outro lado, a classe myCircle precisará armazenar o centro e o raio como variáveis ​​de instância.

myCircle.move(newCenter);
myCircle.resize(newRadius);

Para que o objeto myCircle saiba qual é o seu raio e centro quando essas novas chamadas são feitas, elas precisam ser armazenadas como variáveis ​​de instância, não apenas passadas para as funções que precisam delas.

Então, basicamente, variáveis ​​de instância são uma maneira de salvar o "estado" de um objeto. Se uma variável não é necessária para saber o estado de um objeto, então não deve ser uma variável de instância.

E quanto a tornar tudo público. Isso pode tornar sua vida mais fácil no momento. Mas vai voltar para te assombrar. Por favor, não.

ng.mangine
fonte
Você poderia apenas definir mover para usar os parâmetros (oldCenter, newCenter).
obesechicken13
4

NA MINHA HUMILDE OPINIÃO:

Se a variável faz parte do estado da instância, então deve ser uma variável de instância - classinstance HAS-A instancevariable.

Se eu me descobrisse passando algo repetidamente para os métodos de uma instância, ou descobrisse que tinha um grande número de variáveis ​​de instância, provavelmente tentaria olhar meu projeto para o caso de ter perdido algo ou feito uma abstração ruim em algum lugar.

Espero que ajude

Brabster
fonte
3

Claro que é fácil manter uma grande lista de variáveis ​​públicas na classe. Mas mesmo intuitivamente, você pode dizer que esse não é o caminho a percorrer.

Defina cada variável antes de usá-la. Se uma variável suporta a função de um método específico, use-a apenas no escopo do método.

Pense também na segurança, uma variável de classe pública é suscetível a alterações indesejadas do código "externo". Seu objetivo principal deve ser manter todas as variáveis ​​privadas, e qualquer variável que não seja, deve ter uma boa razão para ser.

Sobre passar parâmetros para cima na pilha, isso pode ficar feio muito rápido. Uma regra prática é manter as assinaturas de seu método limpas e elegantes. Se você vir muitos métodos usando os mesmos dados, decida se é importante o suficiente para ser um membro da classe e, se não for, refatore seu código para que faça mais sentido.

Tudo se resume ao bom senso. Pense exatamente onde e por que você está declarando cada nova variável, qual deve ser sua função e, a partir daí, tome uma decisão sobre em qual escopo ela deve residir.

Yuval Adam
fonte
Freqüentemente, você deseja que os métodos sejam públicos, para que possa testá-los de unidade.
obesechicken13