¿Por qué sería ventajoso pasar objetos a través de métodos estáticos?

9

¿Por qué sería una ventaja usar un método estático y pasar la referencia a un objeto como parámetro en lugar de llamar al método en un objeto?

Para aclarar lo que quiero decir, considere la siguiente clase:

public class SomeClass {
    private double someValue;

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

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

En comparación con esta implementación alternativa con un 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++;
    }
}

Mi pregunta no se limita solo a esta clase; cualquier punto en el que pasarías un objeto en lugar de llamarlo a un método es lo que me interesa. ¿Es esto ventajoso? Si es así, ¿por qué?

Addison Crump
fuente
1
Se siente como un olor a código con dos métodos que hacen exactamente lo mismo. Si el método estático simplemente delega al otro método, entonces se sentiría inútil, pero no necesariamente "malo"
Nathan Merrill
13
@NathanMerrill Creo que te estás perdiendo el punto. Él está preguntando si alguna vez hay una situación en la que sería preferible crear y usar el segundo método en lugar del primer método.
@Mego No solo los métodos dados en el ejemplo; Me pregunto si hay algún momento en el que usar métodos estáticos y pasar objetos es mejor que invocar métodos en objetos.
Addison Crump
Presumiblemente, ¿estás pidiendo específicamente Java?
enderland
3
Creo que esta pregunta asume tácitamente que el código orientado a objetos es algún tipo de óptimo. Un enfoque más procesal o funcional conduciría naturalmente al uso de métodos estáticos. ... Sin embargo, duplicar la funcionalidad entre un método estático y uno de instancia es bastante tonto. Espero que sea solo un ejemplo y que el código real del que estás hablando solo tenga la estática.
jpmc26

Respuestas:

34

Un ejemplo trivial: cuando la instancia aprobada puede ser legítimamente nula y desea incorporar el manejo (no trivial) de esto en el método.

9000
fuente
1
ejemplo: String. Compare en C # (creo que hay algo similar en Java)
edc65
Objects.equals () y Objects.compare () son ejemplos en Java, pero no están en la clase original. En la biblioteca estándar de Java, al menos, es común tener un método de instancia en algo como objeto, pero entonces un método estático en un objeto s de clase.
daboross
20

En su ejemplo, el método de instancia es un claro ganador.

En el caso general, puedo pensar en algunas razones en las que un método estático podría ser apropiado:

  • Desea colocar el método estático en otra clase, ya que tiene una situación en la que tiene sentido separar la lógica de los datos (nota: su ejemplo no es uno de ellos).

  • Está pasando dos o más objetos y desea enfatizar que son de igual importancia.

  • null es un valor válido (como lo explicó el usuario 9000).

Heinzi
fuente
5

Sería conveniente incluir los métodos que cambian el estado del objeto como métodos de instancia en lugar de método estático .

Sin embargo, podemos encontrar ejemplos de métodos estáticos que son puremétodos y tomar el objeto como entrada, como cuando necesitamos instanciar el objeto en función de ciertas reglas de validación. Por ejemplo, .NET tiene el método DateTime.TryParse(String s, DateTime d)para validar e instanciar el objeto. Pero el parámetro DateTime destá marcado explícitamente como out.

Otro caso puede ser cuando comparamos los objetos y queremos obtener el objeto deseado como valor de retorno en lugar de un valor booleano / entero de resultado de comparación, por ejemplo Team.GetHigherScorer(teamA, teamB).IncreaseRanking(),. Esto será más limpio que:

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

(dejando el caso "dibujar" por simplicidad).

maravilla
fuente
1
Uno no pasa un "objeto completo". Se pasa la referencia a un lugar en la memoria, que es una cantidad muy pequeña de datos que se pasan. No estoy seguro del efecto sobre el rendimiento que eso tiene, pero sin embargo ... también, ¿qué implica el marcado "fuera"?
Addison Crump
1
Eliminé la palabra 'completo' de mi declaración, era confuso. Nunca tuve la intención de rendimiento o tamaño, la respuesta se basa únicamente en prácticas de programación. De todos modos, outes una .Netpalabra clave utilizada como modificador de parámetros. Establece que el parámetro se pasa por referencia. Ver para más detalles msdn.microsoft.com/en-us/library/t3c3bfhx.aspx
wonderbell
44
La primera oración es simplemente incorrecta. si tenemos class C { int x; static void M() { entonces M es perfectamente capaz de acceder x. Por ejemplo int y = (new C()).x;es legal.
Eric Lippert
@EricLippert :) Estoy seguro de que sabes a qué me refería. Es sorprendente cómo los maestros pueden leer entre líneas. Puede ser que necesite editar esa oración. Para aclarar, algo como esto static void M() { this.x = 1; }no es posible.
wonderbell
1
@wonderbell: No, estoy seguro de que no sabía a qué te referías. Sabía lo que escribiste. Noto que this.xestá mal no porque xno se pueda acceder sino porque thisno existe. No es una cuestión de acceso en absoluto, es una cuestión de existencia .
Eric Lippert
4

La inyección de dependencia sería una buena razón para realizar la llamada al método estático. Suponiendo que la implementación concreta de SomeClasstiene una cadena de herencia o es la implementación de otra clase. Puede usar una imitación de un objeto, pasarlo con fines de prueba para asegurarse de que su método haga lo que se supone que debe hacer, y luego informa sobre ese estado.

Adam Zuckerman
fuente