thinking tecnicas pasos metodologia libro hacer ejemplos como design oop static-methods

design - tecnicas - ¿Por qué los métodos estáticos no se consideran una buena práctica de OO?



metodologia design thinking (7)

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?


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.

--Aclamaciones


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

  • mensajería,
  • retención local y protección y ocultamiento del proceso estatal, y
  • extrema unión tardía de todas las cosas.

De esos tres, el más importante es la mensajería .

Los métodos estáticos violan al menos los mensajes y los enlaces finales.

La idea de la mensajería significa que en OO, el cálculo se realiza mediante redes de objetos autónomos que se envían mensajes entre sí. Enviar un mensaje es la única forma de comunicación / computación.

Los métodos estáticos no hacen eso. No están asociados con ningún objeto. Realmente no son métodos en absoluto , de acuerdo con la definición habitual. En realidad son solo procedimientos. No hay diferencia entre el 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 el despacho 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 cierta 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 relación entre los actores y los objetos está lejos de ser una coincidencia, de hecho, son esencialmente uno y el mismo.) De nuevo, las estáticas (ambos métodos estáticos, y especialmente el estado estático) rompen esa agradable propiedad.


Los métodos estáticos causan un acoplamiento estricto, 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 conectadas, que a menudo conducen a una infraestructura de terceros de la que depende el código, como una base de datos, y hace que sea muy difícil cambiar el comportamiento sin entrar y cambiar el código.


Los métodos estáticos no se consideran una buena práctica de OO debido a los siguientes motivos:

1) Impide la reutilización:

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

2) Object Lifetime es muy largo:

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 ocasionar el desbordamiento de la memoria.

3) También, algunos otros puntos:

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


Los métodos estáticos no son conceptos de OO tan puros porque pueden invocarse sin que un objeto esté realmente asociado a ellos. Usas la clase en sí. Los invocas como este Classname.method(...);


No confunda "conceptos de 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, las malas prácticas consisten en hacer cosas que son confusas, difíciles de mantener, difíciles de usar, etc. Crear métodos estáticos que tomen 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 deben ser estáticas.

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 de OO "puro", Math podría ser un objeto (un singleton, probablemente), y atan2 sería un método de instancia, pero como la función no usa ningún estado en el objeto Math , tampoco es un concepto "OO puro".


Una razón por la que los métodos estáticos no son muy OO que no se haya 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. Prueba 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 ejecutas esto, no obtendrás lo que esperas. 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 podría ingenuamente esperar llamar "no estáticamente" 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 uses 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.