Por que passar objetos por métodos estáticos seria vantajoso?


9

Por que haveria uma vantagem em usar um método estático e passar a referência a um objeto como parâmetro, em vez de chamar o método em um objeto?

Para esclarecer o que quero dizer, considere a seguinte classe:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public void incrementValue() {
        someValue++;
    }
}

Comparado a esta implementação alternativa com um método estático:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public static void incrementValue(SomeClass obj) {
        obj.someValue++;
    }
}

Minha pergunta não está restrita apenas a essa classe; qualquer ponto em que você passe um objeto em vez de chamá-lo em um método é o que me interessa. Isso é sempre vantajoso? Se sim, por quê?


1
Parece um cheiro de código com dois métodos fazendo exatamente a mesma coisa. Se o método estático simplesmente delegada a outro método, em seguida, ele iria se sentir inútil, mas não necessariamente "ruim"
Nathan Merrill

13
@ NathanMerrill Eu acho que você está perdendo o ponto. Ele está perguntando se alguma vez houve uma situação em que seria preferível criar e usar o segundo método em vez do primeiro.

@Mego Não são apenas os métodos dados no exemplo; Estou perguntando se existe algum momento em que usar métodos estáticos e passar objetos é melhor do que chamar métodos em objetos.
Addison Crump

Presumivelmente você está perguntando especificamente sobre java?
Enderland

3
Penso que esta questão pressupõe tácitamente que o código orientado a objetos é algum tipo de ideal. Uma abordagem mais processual ou funcional levaria naturalmente ao uso de métodos estáticos. ... Duplicar a funcionalidade entre um método estático e um de instância é bastante tolo, no entanto. Espero que seja apenas um exemplo e o código real do qual você está falando tenha apenas a estática.
Jpmc26 12/03/16

Respostas:


34

Um exemplo trivial: quando a instância passada pode legitimamente ser nula e você deseja incorporar o tratamento (não trivial) disso ao método.


1
exemplo: String.Compare em C # (eu acho que há algo semelhante em Java)
edc65

Objects.equals () e Objects.compare () são exemplos em Java - mas não estão na classe original. Na biblioteca padrão Java, pelo menos, é comum ter um método de instância em algo como objeto, mas, em seguida, um método estático em um objeto s classe.
daboross

20

No seu exemplo, o método da instância é um vencedor claro.

No caso geral, posso pensar em algumas razões pelas quais um método estático pode ser apropriado:

  • Você deseja colocar o método estático em outra classe, pois há uma situação em que faz sentido separar a lógica dos dados (nota: seu exemplo não é um deles).

  • Você está passando dois ou mais objetos e deseja enfatizar que eles são de igual importância.

  • null é um valor válido (conforme explicado pelo usuário 9000).


5

Seria sensato incluir os métodos que alteram o estado do objeto como métodos de instância , e não como método estático .

No entanto, podemos encontrar exemplos de métodos estáticos que são puremétodos e tomam o objeto como entrada, como quando precisamos instanciar o objeto com base em certas regras de validação. Por exemplo, o .NET possui o método DateTime.TryParse(String s, DateTime d)para validar e instanciar o objeto. Mas o parâmetro DateTime destá explicitamente marcado como out.

Outro caso pode ser quando comparamos os objetos e queremos obter o objeto desejado como valor de retorno, em vez de um valor booleano / inteiro do resultado da comparação, por exemplo Team.GetHigherScorer(teamA, teamB).IncreaseRanking(). Isso será mais limpo do que:

int compareResult = teamA.compareScoreWith(teamB);
if (compareResult == 1)
    teamA.IncreaseRanking();
else if (compareResult == -1) 
    teamB.IncreaseRanking();

(deixando o caso "empate" por simplicidade).


1
Não se passa um "objeto inteiro". Você passa a referência para um local na memória, que é uma quantidade muito pequena de dados sendo transmitidos. Não tenho certeza sobre o efeito no desempenho que isso tem, mas, no entanto ... também, o que implica a marcação "fora"?
Addison Crump

1
Eu deixei cair a palavra 'inteira' da minha declaração, era confusa. Eu nunca pretendi desempenho ou tamanho, a resposta é puramente baseada em práticas de programação. Enfim, outé uma .Netpalavra - chave usada como um modificador de parâmetro. Ele afirma que o parâmetro é passado por referência. Veja para mais detalhes msdn.microsoft.com/en-us/library/t3c3bfhx.aspx
wonderbell

4
A primeira frase está simplesmente errada. se temos, class C { int x; static void M() { então M é perfeitamente capaz de acessar x. Por exemplo, int y = (new C()).x;é legal.
Eric Lippert 12/03

@ EricLippert :) Tenho certeza que você sabe o que eu quis dizer. É incrível como os mestres podem ler nas entrelinhas. Talvez eu precise editar essa frase. Para esclarecimento, algo assim static void M() { this.x = 1; }não é possível.
WonderBar # 03:

1
@ Wonderbell: Não, tenho certeza de que não sabia o que você queria dizer. Eu sabia o que você escreveu. Observo que this.xestá errado não porque xnão pode ser acessado, mas porque thisnão existe. Não é uma questão de acesso , é uma questão de existência .
Eric Lippert 12/03

4

A injeção de dependência seria um bom motivo para executar a chamada para o método estático. Supondo que a implementação concreta de SomeClasstenha uma cadeia de herança ou seja a implementação de outra classe. Você pode usar uma simulação de um objeto, passá-lo para fins de teste para garantir que seu método faça o que deveria e, em seguida, informar sobre esse status.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.