En C#, ¿cuántas líneas antes de una clase deben considerarse refactorizadas?
refactoring class (10)
Una buena regla general es que refactorizo inteligentemente cualquier método de más de 50 líneas.
El recuento no incluye comentarios y espacios en blanco, sino código real. La razón por la que también lo digo de manera inteligente es que hay muchas ocasiones en que una clase de más de 50 líneas es aceptable y no puede o no debe cambiarse.
No tengo una regla general para las clases. Generalmente no reviso las clases para ver si deben ser refactorizadas.
En mi proyecto actual, casi he completado una clase que tiene casi 4000 líneas de largo. Sin embargo, no hay métodos que superen los 50, y la mayoría de las líneas y métodos son privados y no actúan sobre ningún tipo de datos fuera de la clase.
¿Cuál es la regla de oro para las clases de refactorización?
Cuando la clase viola el SRP , es hora de refactorizar.
El principio de responsabilidad única es un principio de programación de computadoras que establece que cada módulo o clase debe ser responsable de una parte única de la funcionalidad proporcionada por el software, y que la responsabilidad debe estar completamente encapsulada por la clase. Todos sus servicios deben estar estrechamente alineados con esa responsabilidad.
En C #, mi regla de oro para las clases es que algo más de 500 líneas se está haciendo demasiado largo. Realmente me gustan los métodos de menos de 10 líneas, y supongo que menos de 20 es aceptable. Creo que realmente depende del contexto.
Esta clase podría ser un candidato para el ejercicio de refactorización de "extraer un objeto que no creas que está ahí".
¿Quizás, por ejemplo, podrías extraer un objeto de método que te permita refactorizar varios de los 50 métodos de línea en miembros de una clase extraída?
Alternativamente, la encapsulación de algunos de los métodos privados que contienen lógica de negocios en un nuevo objeto que colabora con este podría proporcionar una nueva forma de reutilizar este objeto o el extraído.
Una sola línea es suficiente para considerar la refactorización. 40 métodos de cada 50 líneas comienzan a gritar "Soy demasiado complicado, hay otro objeto escondido aquí" en mi oído.
Mi regla de oro es para los métodos, más que para las clases. Si no puedo ver todo el método en la pantalla, es necesario volver a diseñarlo. Por supuesto, los olores tradicionales se aplican.
No diría que hay una "regla de oro" para refactorizar clases grandes. A veces, una clase realmente encapsula mucha lógica empresarial y debería ser tan grande como es. Sin embargo, podrías considerar hacerte algunas preguntas:
(Suponiendo que esté escribiendo código orientado a objetos) ¿Mi código está realmente orientado a objetos? Es decir, ¿sigue el principio de responsabilidad única (gracias, Nebakanezer)? ¿Es esta clase una clase de ayuda? Si es así, ¿cómo podría refactorizar sus métodos en clases de objeto más apropiadas?
¿Tengo una arquitectura sólida? Es decir, ¿estoy haciendo uso de la abstracción y la herencia en lugar de reinventar la rueda en cada clase? ¿Los métodos sobrecargados están llamando a los métodos base según corresponda?
¿Realmente necesito todo este código? ¿Se podría externalizar parte de la lógica utilizando xpath, expresiones lambda o alguna forma de expresiones basadas en bases de datos?
¿Es el código extensible? ¿Es fácil de mantener? ¿Estaba bien diseñado desde el principio o siempre estamos haciendo pequeños parches para intentar solucionar problemas?
Espero que esto ayude un poco; Puede ser difícil refactorizar clases grandes, pero creo que si empiezas a revisar mis preguntas, puedes encontrar bastante rápido que hay espacio para mejorar tu código ... Sé que normalmente lo hago.
Especialmente en el número 1: es muy común que las personas creen un montón de clases de ayudantes en todo el lugar, que está muy orientado a los objetos (en mi opinión). Ese es un tema diferente, pero es posible que desee ver qué es lo que realmente pertenece a la clase que ha hecho y qué podría o debería estar en otra parte.
Como regla general, si la clase es mantenible y flexible, puede que no sea necesario cambiarla. :)
No permita que LOC sea su principal indicador. 50 líneas me parecen muy pequeñas. Con 50 archivos de línea, terminará teniendo un número hostil de archivos de clase en la solución. Su productividad se verá mermada por toda la navegación que realizará entre archivos y su IDE siempre estará llena de demasiadas pestañas. Personalmente trato de organizar las clases en grupos lógicos por espacio de nombres primero. Clase por clase, trato de hacer el código más pequeño y más fácil de leer. A veces, los archivos de clase se hacen grandes. Empiezo a tener una sensación de malestar cuando el archivo de clase tiene más de 2000 líneas. Cualquier cosa menos que eso, trato con cada caso.
Refactoriza siempre que tengas la oportunidad de:
- introducir los patrones de diseño apropiados en lugar del código de espagueti
- reduce la complejidad del código y aumenta la legibilidad
- eliminar código redundante mediante la introducción de una sola llamada de método
- Liberar UI de la lógica de negocios
etcétera etcétera.
EDITAR: Obviamente, la decisión de refactorizar debe tomar en cuenta el tiempo, el pago potencial, otras responsabilidades, etc.
Refactorizar no se trata tanto de reducir el número de LOC, aunque eso es un efecto secundario, sino de mejorar la calidad. Particularmente, usted desea tratar de seguir el principio DRY (Don''t Repeat Yourself) lo más que pueda, razonablemente.
Si sus clases han roto una de las siguientes "reglas", debe considerar refactorizar.
Usted está buscando SOLIDOS , se pueden encontrar screencasts más detallados here .
S RP: principio de responsabilidad única, nunca debe haber más de una razón para que una clase cambie.
O CP: principio cerrado abierto, las entidades de software (clases, módulos, funciones, etc.) deben estar abiertas por extensión pero cerradas por modificación.
L SP: principio de sustitución de liskov, las funciones que usan referencias a clases base deben poder usar objetos de clases derivadas sin saberlo.
I SP: principio de segregación de interfaz, los clientes no deben ser obligados a depender de las interfaces que no utilizan.
D IP: principio de inversión de dependencia:
Los módulos de alto nivel no deben depender de los módulos de bajo nivel. Ambos deben depender de las abstracciones.
Las abstracciones no deben depender de los detalles. Los detalles deben depender de las abstracciones.
Tiendo a ver la complejidad ciclomática de cada miembro en lugar del número de líneas de código para toda la clase.