Estaba mirando las Pautas de codificación de AvSol para C # y estoy de acuerdo con casi todo, pero tengo mucha curiosidad por ver qué piensan los demás de una regla específica.
AV1500
Los métodos no deben exceder las 7 declaraciones Un método que requiere más de 7 declaraciones está haciendo demasiado o tiene demasiadas responsabilidades. También requiere que la mente humana analice las declaraciones exactas para comprender lo que está haciendo el código. Divídalo en múltiples métodos pequeños y enfocados con nombres autoexplicativos.
¿La mayoría de ustedes siguen esta regla? ¿Incluso si hay poco que ahorrar al crear un nuevo método (su código aún está SECO ), aparte de una gran legibilidad? ¿Y su número sigue siendo tan bajo como 7? Yo tendería más hacia 10.
No digo que viole esta regla por todas partes; por el contrario, mis métodos son 95% pequeños y centrados, pero decir que nunca deberías violar esta regla realmente me dejó alucinado.
Realmente solo quiero saber qué piensan todos de NUNCA violar esta regla (es un '1' en el estándar de codificación, lo que significa que NUNCA haga esto). Pero creo que tendría problemas para encontrar una base de código que no lo haga.
case
declaraciones en una chamusquinaswitch
? De cualquier manera, no es más que un requisito idiota e inútil. Quienes lo escribieron no saben nada de programación.Respuestas:
Este es un "olor estándar" para mí. Cada vez que veo estándares de codificación con límites específicos, me preocupo. Casi siempre te encuentras con un caso en el que un método debe ser más grande de lo que permite el estándar (ya sea longitud / recuento de línea, número de variables, número de puntos de salida, etc.). Las normas deberían parecerse más a las directrices y permitir un margen de maniobra suficiente para ejercer un buen juicio. No me malinterpreten, es bueno tener estándares, pero no deberían convertirse en "microgestión por poder".
fuente
Guidlines
para C # 3.0 y 4.0.Por lo general, es una buena idea dividir las cosas en pequeños métodos. Pero lo importante es dividir las cosas donde tenga sentido.
Si no tiene sentido dividirse, entonces no se divida. Este suele ser el caso de algunos procedimientos o código GUI.
Steve McConnell declaró en Code Complete que no siempre eres más productivo cuando usas métodos cortos. Si se divide cuando no tiene sentido, agrega complejidad al código sin ningún beneficio.
Como siempre con las pautas, es bueno recordar por qué existen las restricciones, para que pueda aprender cuándo no se aplica. En la mayoría del código, los métodos serán cortos, o probablemente tenga un problema con DRY o separación de preocupaciones . Pero si no es el caso, entonces está bien.
fuente
Debe considerarse como una regla de oro.
Cosas como "No más de 80 (100,120) columnas de texto", "un punto de salida por método", "no más de 2 niveles de anidamiento", son lo que yo llamaría umbrales para indicadores de olor de código. Si los viola en alguna ocasión, eso no significa necesariamente que el código sea malo. Si se encuentra violando constantemente, entonces algo huele en el código y es posible que desee hacer una pausa y repensar su enfoque.
Para mí, los criterios más importantes son: "¿Es comprensible este código?", "¿Es repetitivo?", "¿Está dividido en lugares lógicos?", "¿Está acoplado de forma flexible?" Hay algunos más, pero creo que la idea básica se puede resumir recordando el consejo de Donald Knuth: "Los programas deben ser leídos por humanos y solo de manera incidental para que las computadoras los ejecuten".
fuente
less
, envim
yemacs
; y el envoltorio automático parece al azar en el mejor de los casos. Los estándares de codificación no son para su beneficio, son para el beneficio de las personas que trabajan en equipo.Nunca me he tomado el tiempo para contar realmente el número de declaraciones en mis métodos, pero me esfuerzo por escribir métodos que realicen limpiamente un único propósito claro. Siempre que su código sea limpio, legible y siga los principios DRY y de responsabilidad única , probablemente haya hecho su trabajo. Creo que dividir arbitrariamente un método para hacer cumplir el límite de siete instrucciones podría hacer que su código sea menos legible / mantenible.
fuente
Es aproximado
Este tipo de reglas no deben tomarse demasiado literalmente. Podrían haber dicho "los métodos deberían ser cortos ". Sin embargo, algunas personas lo habrían interpretado como "menos de 1 página" y otras como "2 líneas como máximo".
Supongo que dijeron "7 declaraciones" para darle una idea aproximada (aunque creo que deberían haber dicho "aproximadamente 7"). Si necesita 9 de vez en cuando, no se preocupe. Pero si está llegando a 20, sabrá que no está en el estadio correcto para esta regla.
fuente
7 es un número completamente arbitrario sin ningún significado.
La complejidad ciclomática es un problema mayor que el número de declaraciones. He visto código que tenía cientos de declaraciones en un solo método (lo que me pareció terrible), pero tenía una complejidad ciclomática de 1 y realmente solo hizo 1 cosa. Solo había muchos pasos. Discutimos dividirlo en métodos más pequeños, pero esos métodos solo serían llamados por este método.
Si bien ese es un caso bastante extremo, el punto es que debe mantener el código SECO y una baja complejidad ciclomática. Eso es más importante que el número de líneas en un método.
Tome una declaración de cambio / caso, por ejemplo. Si tiene más de 7 valores posibles, ¿necesita dividir la evaluación en varios métodos? Por supuesto que no, eso sería una tontería.
La división artificial del código en más métodos solo para mantener el número de declaraciones por debajo de 7 solo empeora su código.
La directriz debe ser Cada método debe hacer 1 cosa y mantener su código SECO.
fuente
Bueno, depende un poco. Escribo mucho código que accede a las bases de datos. El código de la placa de la caldera para el manejo de excepciones tiene más de siete declaraciones en muchos casos. Yo diría que la mejor guía es asegurarse de que su función tenga un propósito
fuente
ps
yrs
y guardar otro. O escriba un métodoList<Row> readDb(String sql, Object... args)
que haga todo el trabajo (solo funciona para los conjuntos de resultados que se ajustan en la memoria, pero obtener demasiados datos generalmente implica que el trabajo debe realizarse en la base de datos de todos modos).Todo es una compensación. El problema con el enfoque propuesto (refactorización en varios métodos y clases para que cada método sea breve) es que, aunque por diferentes razones, conduce a un código ilegible cuando se lleva al extremo.
Imagine un método
foo()
que hace 7 cosas. Se podría argumentar que 7 cosas son demasiado. Quizás en muchos casos tengas razón. Por otro lado, estas 7 cosas podrían estar estrechamente relacionadas; la lógica puede fluir suavemente y leerse como prosa; Es posible que no tenga problemas para entenderlo cuando realmente lo necesite. Lo que podría terminar mucho peor es tener esas 7 cosas distribuidas en un gran árbol fuente, de modo que si observasfoo()
no tienes idea de lo que hace sin mirar en 7 lugares diferentes.Muchas personas tienen reglas como esta en su cabeza, y el resultado es lo que yo pienso como OO spaghetti. Todo está ordenado, en caja en su propio pequeño método o clase, con pequeñas micro transacciones atómicas que ocurren en cada lugar. Pero es imposible llegar a una base de código de este tipo y saber lo que está haciendo. Te pierdes.
fuente
No es una mala directriz. Nunca me he arrepentido de dividir los métodos y las clases (nunca he descubierto que tenía demasiados) siempre y cuando estén agrupados e interrelacionados lo suficientemente bien.
El truco es NO dividirlo verticalmente (solo pellizca un método en un punto y comienza uno nuevo). El truco, al igual que con las pruebas unitarias, es tener en cuenta esa regla desde el principio para que realmente diseñe mejor, pasando 3 o 4 declaraciones a medio método a otro método porque tener una llamada al método describe lo que está haciendo mejor que esas 3 o 4 declaraciones en el medio de su código.
Este tipo de división, incluso si es arbitrario y solo se usa una vez, puede conducir a mejores refactorizaciones posteriores debido a una nueva claridad de código, esto también es cierto para las clases más pequeñas.
Piense en ello como si fuera una unidad de prueba. Si intenta agregar pruebas unitarias después del hecho, es difícil y a veces parece imposible, pero si lo diseña desde el principio, en realidad mejora todo su código.
¿Resumen? Si comparo el olor del diseño de "Usar menos de 7 declaraciones" con el olor del código de "Usé más de 7 declaraciones", prefiero eliminar el olor del código.
fuente
¡Guauu! Nunca esperé encontrar una discusión tan intensa sobre una guía simple que diga más o menos que sus métodos deberían ser muy pequeños. Debido a que siempre son desarrolladores que quieren que sus pautas sean explícitas, elijo 7 porque eso sonaba como un buen umbral.
Algunos de ustedes ya han citado la exención de responsabilidad al comienzo del documento. Pero para ser claros, este documento representa una colección de pautas que intentan ayudarlo a escribir mejor código y diseñar mejores sistemas. Nunca he dicho que algo debería ser una regla, a pesar de que una directriz está marcada como un nivel 1. Esos niveles son simplemente la opinión colectiva de las muchas personas que han estado usando este documento por un tiempo.
Tampoco he afirmado nunca ser un experto. Pero llevo 15 años en esta profesión, con aproximadamente 4 años de experiencia en C ++ y 11 años de experiencia en C #. Originalmente se basó en Industrial Strength C ++, pero lo he estado refinando desde entonces con el aporte de la comunidad.
De todos modos, el punto que estaba tratando de plantear es que debes seguir pensando por ti mismo. Si crees que la directriz de 7 declaraciones no es útil, solo hazla más larga. Diablos, incluso violo esa pauta de vez en cuando. Simplemente lo violo seriamente y acepto las consecuencias.
fuente
Primero: es una guía, no una regla. Se llama una guía, así que trátela como tal. Esto implica que también se requiere su propio juicio (como siempre)
Aparte de eso, puedo pensar en muchos ejemplos de buen código que no se adhiere a esta restricción. Aunque es solo una guía, es pobre.
fuente
Estoy de acuerdo con la declaración sobre mí. Esto es solo una guía y en un mundo perfecto todo sería objetos, reutilizados en cada programa, y el mundo sería un lugar hermoso. No siempre es cierto y, a veces, eso llevaría a una gran cantidad de gastos generales o desperdicio de recursos. Tienes que tener eso en cuenta también.
fuente
Bastante tonto cuando agrega manejo de excepción a la mezcla.
¡Después de "intentar, atrapar, finalmente" te quedan cuatro afirmaciones por método!
También considere un método "validateForm" para un formulario de 20 campos, incluso si maneja todas las validaciones individuales en métodos separados, todavía tiene 20 métodos de validación de campo para invocar. De acuerdo con estas pautas, terminaría con una división inútil como "validateTopOfScreen", "validateMiddleOfScreen" y "validateBottomOfScreen".
fuente
try
/catch
/finally
no son declaraciones en C #. Ver Ecma-334 § 12.3.3.15 y las secciones circundantes. (abreviado) " una declaración try-catch-finally de la forma : try try-block catch (...) catch-block-n finally finally-block "La pregunta es combinar "reglas" con "pautas". Las reglas están destinadas a ser obedecidas: las pautas son consejos que deben hacer que considere lo que está haciendo y si realmente podría hacerse de una mejor manera.
Yo diría que, en promedio, la mayoría de la programación probablemente mejore al seguir las pautas, pero siempre habrá casos en los que seguir las pautas dogmáticamente causará más problemas de los que pretendían resolver. Es por eso que no se presentan como reglas, sino como pautas.
Un respondedor anterior demostró que los escritores de las directrices nunca pretendieron que se aplicaran dogmáticamente e incluyeron declaraciones a tal efecto en su documento.
fuente
Estoy de acuerdo con los comentarios anteriores. 7 para mí es arbitrario y puede ser útil en algunos lenguajes donde ruby, pero para lenguajes como C #, Java, C ++ dudo de esta convención de "7 líneas". Permítanme darles un ejemplo. Mi aplicación actual tiene 22 campos de texto y hago la validación del lado del servidor. El método se llama validateInput () y mi preferencia es validar todos los campos en un mismo método a menos que haya validado algo complejo como checkEmailFormat (). Entonces, básicamente, mi código del método validateInput es 108 líneas con llamadas ocasionales a validación compleja.
Ahora imagine si llamé a 25 métodos para validar cada campo. Si entra un nuevo desarrollador, tendrá que entrar y salir del método principal para saltar a través de 25 métodos que a su vez podrían estar llamando a algunos otros. Está obligado a perderse en grandes proyectos.
Lo que realmente hago para aclarar mi código es proporcionar comentarios limpios que básicamente dicen lo que están haciendo estas 4 líneas, por ejemplo:
validateInput (usuario UserObj) {
// Validar nombre ....... ......
// validar apellido ...... ......
// validar correo electrónico ..... // demasiado complejo para verificar el formato de correo electrónico regular express checkEmailFormat (); .... .....
y así.. }
fuente
Mala regla Con el código para el manejo de excepciones, la configuración de los campos de la base de datos, la validación, ¿cómo pueden la mayoría de los métodos estar bajo siete declaraciones? ¿Nunca deberíamos hacer funciones lambda en línea?
Las líneas de código son un recuento arbitrario de complejidad. Con los métodos de extensión puedo crear código como
fuente
Todos los programadores junior deberían verse obligados a adherirse a este principio. Eso los obligaría a pensar en la estructura de lo que están ocupados, en lugar de simplemente agregar más y más código de líneas.
Actualmente estoy viendo un método de 550 líneas de código con muchas declaraciones if else y continúa y devuelve entretejido. Es basura. Si el programador solo se hubiera visto obligado a pensar en lo que estaba haciendo ...
fuente