2009-02-25 11 views
6

He estado reflexionando sobre un post por Misko Hevery que los métodos estáticos en Java son muerte a prueba. No quiero discutir el tema de la capacidad de prueba, sino más sobre el concepto de métodos estáticos. ¿Por qué la gente lo odia tanto?métodos estáticos hacen de Java un lenguaje pseudo funcional?

Es cierto que no tenemos cierres (pero tenemos funciones anónimas un poco incómodas), lambdas & funciona como objetos de primera clase. En cierto modo, creo que los métodos estáticos se pueden usar para imitar funciones como objetos de primera clase.

+1

Creo que está confundiendo funcional con procedural. Un error común. –

+0

Java no tiene funciones anónimas, puede pensar en clases anónimas. De hecho, Java no tiene funciones ... solo métodos ;-) –

Respuesta

2

Una característica de la programación funcional es la inmutabilidad de los datos. static implica que no necesita un objeto (instancia) que represente el estado, por lo que no es un mal comienzo. Sin embargo, tiene estado en el nivel de clase, pero puede hacer esto final. Dado que los métodos (estáticos) no son en absoluto funciones de primera clase, aún necesitará construcciones feas como clases anónimas para aproximarse a un cierto estilo de programación funcional en Java.

FP se realiza mejor en un lenguaje funcional, ya que tiene el idioma necesario compatibilidad con para cosas como funciones de orden superior, inmutabilidad, transparencia referencial, etc.

Sin embargo, esto no significa que no pueda programar en un estilo funcional en un lenguaje imperativo como Java. También se pueden dar otros ejemplos. No es porque esté programando en Java que está haciendo OOP. Puede programar con datos globales y flujos de control no estructurados (goto) en un lenguaje estructurado como C++. Puedo hacer OOP en un lenguaje funcional como Scheme. Etc.

Steve McConnell menciona la diferencia de la programación en un lenguaje de programación frente en un lenguaje en el código completo (también una referencia muy popular en SO).

Así que, en resumen, si dices que "los métodos estáticos imitan las funciones de primera clase", no estoy de acuerdo.

Si, sin embargo, y creo que este era más el punto que intentabas transmitir, dirías que "los métodos estáticos pueden ayudar a programar en un estilo funcional en Java", estoy de acuerdo.

4

Los métodos estáticos dificultan las pruebas porque no se pueden reemplazar, es así de simple.

¿Cómo pueden los métodos estáticos "imitar" las funciones como objetos de primera clase ? Podría decirse que son peores que cualquier otra cosa en este frente. Puede "imitar" funciones como objetos de primera clase creando interfaces de un solo método, y de hecho Google Collections de Google hace exactamente esto en varios lugares (para predicados, proyecciones, etc.). Eso no se puede hacer con métodos estáticos: no hay forma (aparte de la reflexión) de pasar el concepto de "cuando desee aplicar una función, use este método.

No, no puedo ver cómo ayudan los métodos estáticos aquí. Desalientan el cambio de estado (ya que el único estado disponible es el estado global y cualquier estado mutable pasado a través de los parámetros) pero no ayudan en el lado de "funciones como objetos de primera clase"

C# tiene mejor apoyo a esta (con expresiones lambda y delegados), pero incluso eso no es tan general como podría ser. (Compárese con F #, por ejemplo.)


Como de Java 8, las referencias método permitirá métodos para ser convertidos a las instancias de las interfaces de un solo método apropiado, lo que hará todo esto más relevante. En 2009, que estaba muy lejos ...

+0

¿Por qué querrías reemplazar un método para probar? ¡Quiero probar el método, no el reemplazo! – ThomasD

+1

¿Qué pasa si el método va a un servidor web en el hemishpere opuesto y realmente no quiere eso, ya que sería mejor con datos falsos estáticos. –

+1

+1 al comentario de Anton. Si no puede reemplazar sus dependencias, sus pruebas de "unidad" probarán esas dependencias, así como también el método que realmente están tratando de probar. –

0

Mi mayor objeción contra los métodos estáticos es que no son polimórficos y que no se usan de forma orientada a objetos, sino que uno tiene para usted la clase (no es un objeto) para acceder a ellos.

3

funcional! = Función, y que conste que se afirman que un método! = Función ...

Java es un lenguaje orientado a objetos de tipos estáticos. Java también ha mantenido una pureza relativa de esa manera, pero no está cerca de un lenguaje funcional.

Si bien es cierto que puedes imitar el comportamiento de la programación funcional con programación imperativa, nunca obtendrás esa sintaxis ordenada que querrás tener para el cálculo lambda. En cierto modo, si el lenguaje no es compatible con el cálculo Lambda adecuado, no es un lenguaje de programación funcional.

C++ tiene funciones, pero C++ también tiene clases. C++ por lo tanto tiene dos tipos de funciones, funciones de miembros y funciones. Cuando dices método te refieres a una función miembro. Porque el método se invoca en una instancia de un objeto. Pero cuando dices método estático te refieres simplemente a función (en el sentido C/C++). Este es solo un vocabulario para referirse a elementos de tu código. Y en el código de Java no puede existir fuera de una clase, un método implicaría que pertenece a alguna clase, es decir, tipo.

Hasta ahora, nada de lo que he dicho se refiere a la programación funcional, pero creo que se llega al punto en el que se equivoca.

Le sugiero que consulte los lenguajes de programación funcionales puros como Haskell o Erlang. Porque los lenguajes de programación funcional generalmente tampoco tienen cerradores.

Su afirmación de que los métodos estáticos pueden usarse para imitar funciones como objetos de primera clase me parece realmente extraño. Suena más como un lenguaje de programación dinámico que como programación funcional.

0

Si solo utiliza métodos estáticos, entonces está programando en un estilo procedimental, no orientado a objetos.

Sin embargo, el único contexto en el que puedo pensar que estaría bien es durante las primeras lecciones de programación antes de que se introduzca la orientación del objeto.

0

En Java, no puede asignar una función como argumento a otra función.

En un lenguaje funcional, si usted tiene una función

def addOne(i) = i + 1 

puede pasar eso a otra función que por ejemplo se aplica a todos los elementos de una lista.

En Java, con

public static int addOne(int i) { return i + 1; } 

no hay manera de hacerlo.

Cuestiones relacionadas