2010-10-23 13 views
21

Estoy leyendo Programming Scala. Al comienzo del capítulo 4, el autor comenta que Java admite métodos estáticos, que son "conceptos OO no tan puros". ¿Por qué esto es tan?¿Por qué los métodos estáticos no se consideran una buena práctica de OO?

+6

No estoy seguro de que "no tan puro" se asocie al instante con una mala práctica. – mellowsoon

+0

No es una mala práctica. Simplemente no es una buena práctica, según el autor. – Mike

+1

¿El autor no da ningún razonamiento? –

Respuesta

17

Una razón por la que los métodos estáticos no son muy OO que no se hayan mencionado hasta ahora es que las interfaces y las clases abstractas solo definen métodos no estáticos. Los métodos estáticos no encajan muy bien en la herencia.

Tenga en cuenta también que los métodos estáticos no tienen acceso a "super", lo que significa que los métodos estáticos no pueden anularse en ningún sentido real. En realidad, no pueden ser anulados en absoluto, solo ocultos. Pruebe esto:

public class Test { 
    public static int returnValue() { 
     return 0; 
    } 

    public static void main(String[] arg) { 
     System.out.println(Test.returnValue()); 
     System.out.println(Test2.returnValue()); 
     Test x = new Test2(); 
     System.out.println(x.returnValue()); 
    } 
} 


public class Test2 extends Test { 
    public static int returnValue() { 
     return 1; 
    } 
} 

Cuando ejecuta esto, no obtendrá lo que espera. Test.returnValue() da lo que esperas. Test2.returnValue()oculta el método del mismo nombre en la superclase (no lo anula), y da lo que cabría esperar.

Uno ingenuamente podría esperar "no estáticamente" llamar a un método estático para usar polimorfismo. No es así Cualquiera sea la clase en que se declare la variable, es la que se usa para buscar el método. Esta es una mala forma porque alguien podría esperar que el código haga algo diferente de lo que realmente hace.

Esto no significa, "¡No use métodos estáticos!"Significa que debe reservar el uso de métodos estáticos para aquellas instancias en las que realmente desea que el objeto Class sea propietario del método, y no solo como una forma perezosa de crear un singleton.

+0

Esta respuesta probablemente tiende a tener más sentido de lo que he visto hasta ahora. Romper uno de los conceptos de trinidad ciertamente va contra corriente. – Mike

+0

No es que esté disputando esto, pero el ejemplo que muestra solo se aplica a Java, ¿verdad? IIRC, Java es el único lenguaje OO (que he encontrado) que permite llamar funciones estáticas a través de una instancia de la clase. –

+0

@Jeff: VB.NET también permite este comportamiento sin sentido. –

1

Los métodos estáticos no son conceptos de OO tan puros porque se pueden invocar sin que realmente se asocie un objeto. Usas la clase en sí. Los invocará así Classname.method(...);

+0

¿Qué ocurre si uso algo como Ruby, que admite clases como objetos e invocación estática? De hecho, un objeto estaría asociado con la llamada estática. – Mike

+0

Bueno, no estoy seguro de qué tan asociado a Java fue el autor cuando dijo lo que hizo, pero la cosa es que incluso en Java hay objetos que se crean y administran para representar las clases también, así que esto es un poco discutible , hasta cierto punto. Sin embargo, la simple idea de que tiene un método principal estático y los métodos estáticos que puede invocar sin tener ningún objeto lo hace un poco contrario al paradigma de OOP. –

0

El concepto de OO se refiere a controlar/acceder a los datos de un objeto, pero no es necesario llamar a los métodos estáticos con un objeto y pertenecen a la clase en lugar de a un objeto.

--Cheers

24

No se debe confundir "conceptos OO no tan puros" con "mala práctica". Ser "OO puro" no es una panacea que deba intentar lograr. El hecho de que los métodos estáticos no tomen una variable de instancia como parámetro no significa que no sean útiles. Algunas cosas simplemente no se prestan a los objetos, y no deberían forzarse en ese molde solo por el bien de la "pureza".

Algunas personas piensan que las cosas deben ser "puras", y por lo tanto, cualquier cosa "impura" es una mala práctica. En realidad, una mala práctica es hacer cosas que son confusas, difíciles de mantener, difíciles de usar, etc. La creación de métodos estáticos que toman una instancia es una mala práctica porque cualquier método que tome una instancia probablemente sea un método de instancia. Por otro lado, cosas como la utilidad y las funciones de fábrica generalmente no toman una instancia, por lo que debe ser estático.

Si se pregunta por qué no son "OO puros", es porque no son métodos de instancia. Un lenguaje OO "puro" tendría todo como un objeto y todas las funciones serían métodos de instancia. Por supuesto, eso no es terriblemente útil todo el tiempo. Por ejemplo, considere el método Math.atan2. Toma dos números y no requiere ningún estado. ¿Qué objeto podría incluso convertirlo en un método de? En un lenguaje OO "puro", Math podría ser un objeto (un singleton, probablemente), y atan2 sería un método de instancia, pero dado que la función no usa ningún estado en el objeto Math, tampoco es un concepto "OO puro".

+0

Tenga en cuenta que nunca dije que era una mala práctica, por lo que mi pregunta no fue realmente respondida. ;) – Mike

+2

Es cierto. Por otro lado, he visto demasiados códigos en los que todo es un singleton y todo es estático. Este tipo de código suele ser más difícil de modificar, más difícil de extender, más difícil de remodelar para hacer algo que originalmente no estaba destinado a hacer. Dicho esto, demasiadas personas son demasiado dogmáticas sobre esto. – Eddie

+0

En realidad, la función 'atan2' mide los radianes del ángulo de un * punto único * al eje x positivo. En otras palabras, no debería tomar dos argumentos numéricos en primer lugar, debería tomar un argumento de un solo punto. Lo cual, en términos OO, podría modelarse como un método en un objeto puntual. –

40

La orientación a objetos se trata de tres cosas :

  • mensajería,
  • local de retención y protección y ocultamiento de estado del proceso, y
  • extrema de todas las cosas de enlace tardío

de los tres. , el más importante es mensajes.

Los métodos estáticos infringen al menos la mensajería y la vinculación tardía.

La idea de mensajes significa que en OO, el cálculo se realiza mediante redes de objetos autónomos que se envían mensajes entre sí. El envío de un mensaje es el único forma de comunicación/cálculo.

Los métodos estáticos no hacen eso. No están asociados con ningún objeto. Realmente no son métodos en absoluto, según la definición habitual. En realidad son solo procedimientos. No hay diferencia entre un método estático de Java Foo.bar y una subrutina BASIC FOO_BAR.

En cuanto a la vinculación tardía: un nombre más moderno para eso es envío dinámico. Los métodos estáticos violan eso, también, de hecho, incluso está en su propio nombre: métodos estáticos.

Los métodos estáticos rompen algunas propiedades muy agradables de la orientación a objetos. Por ejemplo, los sistemas orientados a objetos son automáticamente seguros para las capacidades con objetos que actúan como capacidades. Los métodos estáticos (o realmente cualquier estática, ya sea estado estático o métodos estáticos) rompen esa propiedad.

También puede ejecutar cada objeto en paralelo en su propio proceso, ya que solo se comunican a través de mensajes, lo que proporciona una simultaneidad trivial. (Como Actors, básicamente, lo cual no debería ser demasiado sorprendente, ya que Carl Hewitt creó el Actor Model basado en Smalltalk-71, y Alan Kay creó Smalltalk-71 parcialmente basado en PLANNER, que a su vez fue creado por Carl Hewitt. La estrecha relación entre actores y objetos está lejos de ser una coincidencia, de hecho, son esencialmente uno y el mismo.) De nuevo, los estáticos (ambos métodos estáticos, y especialmente el estado estático) rompen esa bonita propiedad.

+0

Esta es también una excelente respuesta. Ojalá pudiera aceptar más de uno. Gracias. – Mike

1

Los métodos estáticos causan un acoplamiento apretado, lo cual es una violación del buen diseño orientado a objetos. El acoplamiento estricto del código de llamada y el código dentro del método estático no se puede evitar a través de la Inversión de Dependencia porque los métodos estáticos no son compatibles con las técnicas de diseño orientadas a objetos como la herencia y el polimorfismo.

Además, los métodos estáticos son difíciles de probar debido a estas dependencias estrechamente acopladas, que a menudo conducen a una infraestructura de terceros de la que el código depende, como una base de datos, y hace que sea muy difícil cambiar el comportamiento sin funcionar realmente. en y cambiando el código.

0

Los métodos estáticos no se consideran buenas prácticas OO debido a razones siguientes:

1) impide Re-usabilidad:

Los métodos estáticos no pueden ser sobreescritos. No se puede usar en la interfaz.

2) duración de los objetos es muy larga:

Los métodos estáticos permanecen en la memoria durante un tiempo de registro y su recolección de basura lleva mucho tiempo. Los desarrolladores no tienen control sobre la destrucción o creación de variables estáticas. El uso excesivo de variables estáticas puede provocar el desbordamiento de la memoria.

3) Además, algunos otros puntos:

no respeta la encapsulación porque objeto does't permanecen en el control completo de su estado. No sigue conceptos como Inversión de control, acoplamiento flojo, inyección de dependencia, etc.

Cuestiones relacionadas