variable usar metodos metodo estaticos estatico cuando clases c# java oop

usar - static void main c#



¿Hay algo mal con una clase con todos los métodos estáticos? (16)

Estoy revisando el código y encontré una clase que usa todos los métodos estáticos. El método de entrada toma varios argumentos y luego comienza a llamar a los otros métodos estáticos que pasan a lo largo de todos o algunos de los argumentos que recibió el método de entrada.

No es como una clase de Matemáticas con funciones de utilidad en gran parte no relacionadas. En mi propia programación normal, rara vez escribo métodos donde Resharper aparece y dice "esto podría ser un método estático", cuando lo hago, tienden a ser métodos de utilidad sin sentido.

¿Hay algo mal con este patrón? ¿Es solo una cuestión de elección personal si el estado de una clase se mantiene en campos y propiedades o se pasa entre métodos estáticos usando argumentos?

ACTUALIZACIÓN : el estado particular que se está transmitiendo es el conjunto de resultados de la base de datos. La responsabilidad de la clase es rellenar una plantilla de hoja de cálculo de Excel de un conjunto de resultados del DB. No sé si esto hace alguna diferencia.


¿Hay algo mal con este patrón? ¿Es solo una cuestión de elección personal si el estado de una clase se mantiene en campos y propiedades o se pasa entre métodos estáticos usando argumentos?

Desde mi propia experiencia personal, he trabajado en 100 aplicaciones KLOC que tienen jerarquías de objetos muy profundas, todo hereda y anula todo lo demás, todo implementa media docena de interfaces, incluso las interfaces heredan media docena de interfaces, el sistema implementa cada patrón de diseño en el libro, etc.

Resultado final: una arquitectura verdaderamente OOP-tastic con tantos niveles de indirección que lleva horas depurar cualquier cosa. Recientemente comencé un trabajo con un sistema como este, donde la curva de aprendizaje me fue descrita como "una pared de ladrillo, seguida de una montaña".

A veces, OOP demasiado entusiasta da lugar a clases tan granulares que en realidad es un daño neto.

Por el contrario, muchos lenguajes de programación funcionales, incluso los OO como F # y OCaml (y C #!), Fomentan la jerárquica plana y superficial. Las bibliotecas en estos idiomas tienden a tener las siguientes propiedades:

  • La mayoría de los objetos son POCO, o tienen como máximo uno o dos niveles de herencia, donde los objetos no son mucho más que contenedores para datos lógicamente relacionados.
  • En lugar de que las clases se llamen entre sí, tiene módulos (equivalentes a clases estáticas) que controlan las interacciones entre objetos.
  • Los módulos tienden a actuar sobre un número muy limitado de tipos de datos, por lo que tienen un alcance limitado. Por ejemplo, el módulo de lista OCaml representa operaciones en listas, un módulo Cliente facilita las operaciones en los clientes. Mientras que los módulos tienen más o menos la misma funcionalidad que los métodos de instancia en una clase, la diferencia clave con las bibliotecas basadas en módulos es que los módulos son mucho más autónomos, mucho menos granulares y tienden a tener pocas o ninguna dependencia en otros módulos.
  • Por lo general, no es necesario subclasificar los métodos de anulación de objetos, ya que puede pasar las funciones como objetos de primera clase para la especialización.
  • Aunque C # no es compatible con esta funcionalidad, los functors proporcionan un medio para subclasificar los módulos especializados.

La mayoría de las bibliotecas grandes tienden a ser más anchas que profundas, por ejemplo, la API Win32, bibliotecas PHP, BIFs Erlang, bibliotecas OCaml y Haskell, procedimientos almacenados en una base de datos, etc. Así que este estilo de programación es prueba de batalla y parece funcionar bien en el mundo real.

En mi opinión, las API basadas en módulos mejor diseñadas tienden a ser más fáciles de trabajar que las API OOP mejor diseñadas. Sin embargo, el estilo de codificación es tan importante en el diseño de API, por lo que si todos los miembros de tu equipo usan OOP y alguien se ejecuta e implementa algo en un estilo completamente diferente, entonces probablemente deberías solicitar una reescritura para que coincida más con la codificación de tu equipo. estándares.


"el estado de una clase es ... transmitido entre métodos estáticos usando argumentos?" Así es como funciona la programación de procedimientos.

Una clase con todos los métodos estáticos y sin variables de instancia (excepto las constantes finales estáticas) es normalmente una clase de utilidad, por ejemplo, matemática. No hay nada de malo en hacer una clase de unicidad, (no en sí misma). Por cierto: si se hace una clase de utilidad, se debe evitar que la clase aver se use para crear un objeto. en java, harías esto al definir explicitamente el constructor, pero haciendo que el constructor sea privado. Mientras que, como dije, no hay nada de malo en crear una clase de utilidad, si la mayor parte del trabajo está siendo realizada por una clase de utiulity (lo que significa que no es una clase en el sentido habitual, es más una colección de funciones) esto es un problema como signo de que el problema no se ha resuelto utilizando el paradim orientado a objetos. esto puede o no ser algo bueno

El método de entrada toma varios argumentos y luego comienza a llamar a los otros métodos estáticos que pasan a lo largo de todos o algunos de los argumentos que recibió el método de entrada. por el sonido de esto, toda la clase es solo un método (este sería definitivamente el caso). Todos los otros métodos estáticos son privados (y son solo funciones auxiliares), y no hay variables de instancia (constantes de desprotección). Esto puede estar y ok, es esc. Programación estructurada / procesal, más bien tenerlos (la función y su ayuda) todos agrupados en una clase. (en C, simplemente los pondría todos en un archivo y declarará que el helper está estático (es decir, no se puede acceder desde el exterior de este archivo))


¿Ayuda a reformular la pregunta?

¿Puede describir los datos en los que opera los métodos estáticos como una entidad que tiene:

  • un significado claro
  • la responsabilidad de mantener su estado interno constante.

En ese caso, debe ser un objeto instanciado; de lo contrario, puede tratarse de un conjunto de funciones relacionadas, muy parecido a una biblioteca matemática.


Aquí hay un flujo de trabajo de refactorización que encuentro con frecuencia que involucra métodos estáticos. Puede aportar cierta información sobre su problema.

Empezaré con una clase que tiene una encapsulación razonablemente buena. A medida que empiezo a agregar funciones, me encuentro con una funcionalidad que no necesita acceso a los campos privados de mi clase, pero que parece contener funcionalidades relacionadas. Después de que esto sucede algunas veces (a veces solo una vez) empiezo a ver los contornos de una nueva clase en los métodos estáticos que he implementado y cómo esa nueva clase se relaciona con la clase anterior en la que primero implementé los métodos estáticos.

El beneficio que veo al convertir estos métodos estáticos en una o más clases es que, al hacer esto, con frecuencia es más fácil de entender y mantener su software.


Bueno, personalmente, tiendo a pensar que un método que modifique el estado de un objeto debería ser un método de instancia de la clase de ese objeto. De hecho, lo considero como una regla: un método que modifica un objeto es un método de instancia de la clase de ese objeto.

Sin embargo, hay algunas excepciones:

  • métodos que procesan cadenas (como mayúsculas de sus primeras letras o ese tipo de característica)
  • método que no tiene estado y simplemente ensamblar algunas cosas para producir una nueva, sin ningún estado interno. Obviamente son raros, pero en general es útil hacerlos estáticos.

De hecho, considero que la palabra clave estática es lo que es: una opción que debe usarse con cuidado ya que rompe algunos de los principios de OOP.


Depende de si los argumentos pasados ​​realmente pueden clasificarse como estado .

Tener métodos estáticos llamando entre sí está bien en caso de que toda la funcionalidad de la utilidad se divida en múltiples métodos para evitar la duplicación. Por ejemplo:

public static File loadConfiguration(String name, Enum type) { String fileName = (form file name based on name and type); return loadFile(fileName); // static method in the same class }


El mayor problema de la OMI es que si desea que las clases de prueba unitarias llamen a la clase que menciona, no hay forma de reemplazar esa dependencia. Entonces, se ven obligados a probar tanto la clase de cliente como la clase llamada estáticamente de una vez.

Si estamos hablando de una clase con métodos de utilidad como Math.floor (), esto no es realmente un problema. Pero si la clase es una dependencia real, por ejemplo un objeto de acceso a datos, entonces vincula a todos sus clientes a su implementación.

EDITAR: No estoy de acuerdo con la gente que dice que ''no hay nada malo'' con este tipo de ''programación estructurada''. Yo diría que una clase como esta es al menos un olor a código cuando se encuentra dentro de un proyecto Java normal, y probablemente indica malentendido del diseño orientado a objetos por parte del creador.


Lo que describes es simplemente una programación estructurada, como se podría hacer en C, Pascal o Algol. No hay nada intrínsecamente equivocado con eso. Hay situaciones en las que OOP es más apropiado, pero OOP no es la respuesta definitiva y si el problema en cuestión es mejor atendido por la programación estructurada, entonces una clase llena de métodos estáticos es el camino a seguir.


Nada está mal con eso. Es una forma más "funcional" de codificar. Puede ser más fácil de probar (porque no hay un estado interno) y un mejor rendimiento en tiempo de ejecución (porque no hay sobrecarga para instanciar un objeto inútil).

Pero inmediatamente pierde algunas capacidades OO. Los métodos estáticos no responden bien (en absoluto) a la herencia. Una clase estática no puede participar en muchos patrones de diseño, como el localizador de fábrica / servicio.


No estoy muy seguro de lo que quieres decir con el método de entrada, pero si estás hablando de algo como esto:

MyMethod myMethod = new MyMethod(); myMethod.doSomething(1); public class MyMethod { public String doSomething(int a) { String p1 = MyMethod.functionA(a); String p2 = MyMethod.functionB(p1); return p1 + P2; } public static String functionA(...) {...} public static String functionB(...) {...} }

Eso no es aconsejable.

Creo que usar todos los métodos estáticos / simples es una buena manera de codificar la lógica de su negocio cuando no tiene que insistir en nada de la clase. Tiendo a usarlo sobre singletons, pero eso es simplemente una preferencia.

MyClass.myStaticMethod(....);

Opuesto a:

MyClass.getInstance().mySingletonMethod(...);

Todos los métodos / singleton estáticos tienden a usar menos memoria también, pero dependiendo de la cantidad de usuarios que tenga, es posible que ni siquiera lo note.


No hay nada de malo en este patrón. De hecho, C # tiene una construcción llamada clases estáticas que se utiliza para respaldar esta noción haciendo cumplir el requisito de que todos los métodos sean estáticos. Además, hay muchas clases en el marco que tienen esta característica: Enumerable , Math , etc.


No, muchas personas tienden a crear clases completamente estáticas para las funciones de utilidad que desean agrupar en un espacio de nombres relacionado. Hay muchas razones válidas para tener clases completamente estáticas.

Una cosa a tener en cuenta en C # es que muchas clases previamente escritas completamente estáticas ahora son elegibles para ser consideradas como clases de extensión .net que también están en su corazón como clases estáticas. Muchas de las extensiones de Linq se basan en esto.

Un ejemplo:

namespace Utils { public static class IntUtils { public static bool IsLessThanZero(this int source) { return (source < 0); } } }

Que luego te permite simplemente hacer lo siguiente:

var intTest = 0; var blNegative = intTest.IsLessThanZero();


Pasar todos los estados como parámetros del método puede ser un patrón de diseño útil. Asegura que no hay un estado mutable compartido, por lo que la clase es intrínsecamente segura para subprocesos. Los servicios se implementan comúnmente utilizando este patrón.

Sin embargo, pasar todos los estados a través de los parámetros del método no significa que los métodos tengan que ser estáticos; aún puede usar el mismo patrón con métodos no estáticos. Las ventajas de hacer que los métodos sean estáticos es que el código de llamada solo puede usar la clase al hacer referencia por su nombre. No hay necesidad de inyección o búsqueda ni de ningún otro intermediario. La desventaja es la capacidad de mantenimiento: los métodos estáticos no son despachos dinámicos, y no se pueden subclasificar fácilmente, ni se pueden refabricar a una interfaz. Recomiendo usar métodos estáticos cuando intrínsecamente solo hay una implementación posible de la clase, y cuando hay una razón sólida para no usar métodos no estáticos.


Siento que si se requiere que la clase mantenga algún tipo de estado (por ejemplo, propiedades), entonces debe crearse una instancia (es decir, una clase "normal").

Si solo debe haber una instancia de esta clase (de ahí todos los métodos estáticos), entonces debe haber una propiedad / método singleton o un método de fábrica que cree una instancia de la clase la primera vez que se llame, y luego solo proporcione esa instancia cuando cualquier otra persona lo pide.

Habiendo dicho eso, esta es solo mi opinión personal y la forma en que lo implementaría. Estoy seguro de que otros no estarían de acuerdo conmigo. Sin saber nada más, es difícil dar razones por / contra cada método, para ser honesto.


Una de las desventajas de utilizar una clase estática es que sus clientes no pueden reemplazarla por una prueba doble para que se prueben las unidades.

De la misma manera, es más difícil probar la unidad de una clase estática porque sus colaboradores no pueden ser reemplazados por dobles de prueba (en realidad, esto sucede con todas las clases que no son de inyección de dependencia).


si no hay necesidad de crear un objeto de una clase, entonces no hay problema en crear todo el método como estático de esa clase, pero quiero saber qué estás haciendo con una clase llena de métodos estáticos.