Dec 15, 2010

Regiones en C# - Más de lo mismo

Durante la discusión del artículo "Comentarios - No, no, y no" se mencionó el uso de las regiones en C#. Es muy probable que todo el que ha tenido alguna vez que enfrentarse al Visual Studio .NET esté familiarizado con esta directiva, la cual permite especificar bloques de código que pueden ser expandidos o cerrados utilizando la opción "outlining" del IDE. Bastante popular a juzgar por la cantidad de veces que la he encontrado en ejemplos y código de terceros, y, como muchos podrán imaginarse, impopular para mí y completamente fuera de mi diccionario.

Después de hacer un esfuerzo para no ser tan drástico (y créanme que lo intenté de veras), la única ventaja que puedo encontrar para el uso de las regiones es ocultar alguna porción en nuestro código ajena a la implementación del mismo. Digamos que una sección de documentación muy larga, o un código autogenerado por alguna herramienta... Y siendo sinceros, si lo pienso nuevamente voy a comenzar a cuestionarme qué hace dicha sección de documentación allí, o cómo es posible que estemos mezclando un código autogenerado en nuestra propia clase... así que mejor ni lo pienso.

Por otra parte, cada vez que voy a trabajar en un nuevo proyecto cuyos desarrolladores son fans de las regiones, mi primera operación es desactivar el Numlock del keypad (nada que ver con las regiones pero es lo que siempre hago), y luego desactivar el outlining en Visual Studio .NET para poder ver todo el código sin que las regiones interfieran. Si consigo el permiso, eliminar los #region y #endregion es siempre uno de los primeros pasos de limpieza general y refactorización.

¿Pero cuál es mi problema con las regiones?

  • Su principal objetivo es "ocultar". ¿Qué sentido tiene esto? ¿Acaso a un mecánico de autos le gustaría que el fabricante hiciese lo posible por esconder tuercas y tornillos? ¿Acaso no tenemos que abogar por aumentar legibilidad y claridad en el código? La última vez que revisé, ocultar" es precisamente lo opuesto.
  • Otra de sus funciones es "agrupar". No puedo imaginarme cómo esto puede ayudar. ¿Agrupar secciones de código dentro de un método? Para eso existen las subrutinas. ¿Agrupar miembros del mismo tipo? Completamente sin sentido. ¿Agrupar funcionalidad relacionada? Para eso existen las clases.
  • Su uso más popular es sin lugar a dudas el de esconder lo que no queremos ver. Sí, esas 500 líneas de código horrible que no hemos podido arreglar, o aquel método que nunca entendimos, o incluso esas 30 veces que hemos duplicado lo mismo y ahora queremos empujarlo bajo un "#region Refrescar la pantalla" (¿la palabra "método" le suena a alguien"?).
  • Las regiones no son más que otra forma de comentar el código. La diferencia es que ahora tienes la posibilidad incluso de ocultar lo que realmente tiene valor (líneas ejecutables) en favor de texto completamente inútil (el nombre de la región -o comentario, como prefieran llamarle).

Al igual que siempre, el debate está abierto y me gustaría oír el criterio de todos al respecto. Un último detalle antes de terminar: Si estás en la lista de los amantes de los comentarios, y también te sientes atraído por las regiones, es muy probable que hayas confundido la profesión. Posiblemente como escritor seas más feliz.

15 comments:

  1. Todo depende de como el equipo use "Regions". Yo generalmente lo use para agrupar campos y propiedades, metodos y manejadores de eventos. Si ya declare mis campos y propiedades, no veo razon alguna para estarlo viendo todo el tiempo.A la misma vez , no soporto regiosn dentro de un metodo, pq si, realmente es para ocultar un codigo del q no estamos muy orgullosos.
    No creo q las regiones sea una forma de documentacion,simplemente es una forma de agrupar y te ayuda a enforcarte en la seccion del codigo q te interesa.
    A la misma vez se q tienden a confundir , por el siemple hecho de q esconde secciones del codigo. Pero como dije , todo en extremo es malo. LAs herramientas estan alli, y como uno las quiera usar. Nada q todo depende de como se use.

    ReplyDelete
  2. La posibilidad de hacer algo siempre es un sentimiento poderoso y placentero. Soy amigo de este tipo de libertad, pero del mismo modo considero que muchas veces resulta más dañino que beneficioso. Dale a un mono una pistola y mételo en un elevador lleno de personas... Nada bueno puede suceder allí dentro. Del mismo modo dale herramientas a desarrolladores de pacotilla y ellos te harán la vida un yogourt sin sabor.

    Muchas veces miramos solamente desde el punto de "yo lo hago bien pues lo utilizo para esto y aquello", pero olvidamos lo que los demás hacen. Un desarrollador pasa mucho más tiempo en el código de terceros que en el suyo propio, así que yo comenzaría a preocuparme un poco más por sobre lo que los demás están haciendo.

    La pregunta es, ¿son las regiones lo suficientemente beneficiosas para nosotros como para pasar por alto todos sus problemas? No lo creo. Independientemente que podamos buscarle algún buen uso (y que yo no veo), aún tendrán 100,000 usos incorrectos, y esos son los que nos convierten los días en una pesadilla.

    Again, dale a un mono una pistola y...

    ReplyDelete
  3. Completamente de acuerdo con Nelsito. Incluso poniendome en el lugar de un programador utilizando código de terceros, le agradecería que me agrupara en regiones las propiedades y métodos de la forma que Nelsito señala (sobre todo cuando son muchas). No veo las regiones como una herramienta para ocultar (pues le das click a + y listo ahi esta el código), en todo caso son para organizar. Acaso no se podría decir lo mismo del code folding que hacen practicamente todos los IDEs a los métodos y las clases?, igualmente estan ocultando lineas ejecutables.

    Por supuesto todo esta en el gusto y las costumbres del programador, pero me parece que es exajerado llamar programador de pacotilla a aquel que use regiones, e incluso ni siquiera al que use comentarios en general.

    Vaya no es nada personal yo no uso comentarios inecesarios (o trato de evitalos) pero no creo que el uso o no de los mismos sea medidor de la calidad de un programador.

    ReplyDelete
  4. Oh, sorry, me disculpo pues a lo mejor no me expresé bien. Yo no quise decir que el que use regiones es un programador de pacotilla. Para nada pienso eso. Yo digo que "hay programadores de pacotilla", y que ellos "usan regiones" y que casi siempre "las usan mal". Yo no digo que todo el que tenga una pistola es un mono, sino que hay monos con pistola.

    Yanier sí, estamos de acuerdo que las regiones son prácticamente lo mismo que el code folding, con la diferencia que las regiones permiten "agrupar" lo que quieras mientras que el code folding es solo métodos o clases. El code folding no viaja con tu código. Si tú quieres ocultar todos tus métodos, felicidades, pero yo en mi PC los veré todos abiertos. Las regiones sin embargo son persistentes, y todos tenemos que comernos el gusto personal de los demás.

    En cuanto a agrupar las propiedades y métodos... y aquí de nuevo entra el gusto de cada cual... mi opinión es:

    1) Si son muchas propiedades, es probable que tu clase necesites dividirla en varias clases.

    2) Si son muchos métodos, es o que necesitas más clases, o que las responsabilidades no están bien distribuidas.

    3) Si son pocas propiedades y métodos, no veo el punto en ocultarlas.

    4) Cuando están ocultas no puedo ver lo que hay escrito. Tengo que darle al + todo el tiempo o desactivar el outlining.

    Cuando abres una clase y ves:

    + [Campos]
    + [Propiedades]
    + [Constructores]
    + [Metodos]

    ¿Que haces con ello? ¿Decir que está organizado todo? Yo tambien lo organizo todo JUNTANDO los campos, las propiedades, los constructores, y los métodos... pero no tengo que meterlos en una cajita con una etiqueta afuera. Cada vez que quiero ver algo tengo que darle al +. Sorry, pero gracias.

    ReplyDelete
  5. yudielgc12/15/2010

    Estoy de acuerdo que para hacer algo más legible el código (legible a mi modo de ver) hagamos regiones donde separemos lo público de lo privado, así como alguna otra característica especial que queramos remarcar, definiendo de esta manera los grandes bloques globales de nuestra clase.

    Si bien como dice Santiago no es sinómino de mejor organizado la mayoría de los desarrolladores que conozco practican esta técnica y por supuesto, no por esto son más organizados, simplemente les gusta agrupar sus bloques a conveniencia personal o del grupo.

    En fin, a gusto de consumidor pero sin ni abusos ni pistola en mano.

    En realidad no es gran cosa, ni para bien ni para mal.

    ReplyDelete
  6. Yudiel, eso incluso es otro modo de verlo. Si te fijas los anteriores comentarios son respecto a agrupar por tipo: "los campos", "los métodos", "las propiedades". Tú propones por visibilidad, y estoy seguro que si seguimos oyendo comentarios alguien va a proponer una manera diferente completamente. Resultado: todo el mundo hace lo que quiere... todo el mundo sufre con el código de otros.

    ¿Qué tal si en vez de implementar las regiones de esta manera se hacen como una opción del IDE (like the coding folding feature)? De este modo, dos desarrolladores pueden organizar el código como deseen sin afectar al resto.

    ReplyDelete
  7. Es cierto que no son la gran cosa pero sí creo que son útiles.
    Cuando veo esto:
    + [Campos]
    + [Propiedades]
    + [Constructores]
    + [Metodos]
    No solo digo que está organizado, sino que me ahorro cantidad de tiempo en scroll. Por otra parte no es dar click en el + cada vez que quiero ver algo, simplemente si dejo la región expandida cuando abra el fichero otro día así estará (Si Visual Studio lo recuerda). Si deseo ver todo el código presiono el short cut (Ctrl, M,L) y listo.
    Es cierto que las regions viajan con el código, sin embargo no tengo las estadísticas pero al menos en mi entorno de trabajo y en los programadores de c# que tengo cerca más del 90% usan VS con outlining activado e incluso muchos hacen uso de Regions, ergo si en realidad voy a pensar en terceros que utilizarán mi código lo hago pensando en ese 90% y no en el otro 10%, que si tienen el outlining desactivado no creo que les haga mucho daño un #region en el código, o en todo caso no se compara con el bien que le hará al otro 90% que si lo apreciará.
    Regions es un ejemplo pequeño de extensión del lenguaje, ejemplos más grandes son linq, y demás, que igualmente pueden ser utilizados mal, pero que son herramientas que están ahí para bien.

    El tema de agrupar los campos de una clase grande en otras clases, es la opción ideal, y no hay que ser un genio de POO para saberlo, solo que a veces no se posible o viable sin hacer cambios significativos a la aplicación para lo cual si no nos pagan bien (como acá en cuba) no sé porque no encontramos la motivación para hacerlo jeje. Y entonces las regiones vienen como anillo al dedo como una solución rápida y para mi gusto relativamente decente (no óptima).

    Bueno Santiago en general yo estoy de acuerdo contigo en todo este tema de comentarios porque para empezar no me gusta escribir y cuando lo hago muchas veces tengo que pasar corrector ortográfico para estar seguro de lo que escribo, pero es que me gusta tanto cuando veo un código ajeno que no se explica por sí solo pero que al menos esta comentado, que me cuesta ponerme en contra de los comentarios. Y sinceramente yo mismo mientras no se me page bien, no invierto mi tiempo arreglando código que ya funciona para que quede mejor, así que por ahora tengo que vivir con los comentarios.

    Saludos y felicidades por el Blog no se si soy yo solo pero en IE8 la foto sale abajo despues del texto, en firefox esta OK, parece que atrae bastante gente no le vayas a poner adds jeje.

    ReplyDelete
  8. Ja, Internet Explorer como siempre dando la talla. No me había dado cuenta, gracias por decirme. Lo voy a arreglar ahora. En cuanto a los ads, ya veremos :)

    ReplyDelete
  9. Realmente si hay algo que me moleste mas que un #REGION son dos #REGIONs :)

    Aprovecho la oportunidad para recalcar que los COMMENTS tampoco son de mucha utilidad, amen que sea para algo asi como esto:
    // security issue: www.microsoft.com/kb9838303

    ...o sea acotar un tema tecnico digno de una revision posterior para el que le de la gana de leerlo.

    Para leer el codigo no hay nada mas bonito que una clase con pocas responsabilidades, con metodos super pequeños y concretos y una correcta metodologia de formatear el codigo. Teniendo estos puntos en consideracion no hacen falta los COMMENTS, por no decir que los REGIONS si no sirven absolutamente para nada de nada.

    Esta es mi humilde opinion.

    ReplyDelete
  10. Vaya, bienvenido Jorge. Al menos alguien en mi favor :) Jorge, se ve que tú y yo somos de la misma escuela :)

    ReplyDelete
  11. With every "feature" whether in the IDE or the programming language itself there is increased responsibility on the part of the developer. For the experienced and knowledgeable developer a language with rich features is much more desirable than a lesser feature rich language.

    The #region pre-processor command is the first pre-processor command I've ever seen that does NOTHING regarding functionality. What is absolutely appalling to me is the requirement for a matching #endregion statement on a completely meaningless command. This requirement is thrown by the C# compiler itself (CSC.EXE) and also tells me that it's considered a pre-processor command even though Microsoft would have you think otherwise. This is absurdity at its worst.

    Seeing as it's not really a "feature" of the language but really of the IDE and that Visual Studio mainly uses it to hide what Microsoft would consider "boring code" I don't see any benefit for the #region command. The developer gains nothing through its use except to segment code without separating code. I've used it to segment UI event handlers from core processing methods. Usually the event handlers would set a few variables and call a processing method of some sort to do the actual work. It is easier to navigate the source code without seeing the half-dozen event handling methods that are only 3-4 lines of code. You could alternately just move the boring code to the end of the file and keep the interesting stuff at the top. What's annoying though is the use of #region's inside of while loops and if-then statements that are 500 lines long. Just because it's big doesn't mean it should be a region. Region's should NEVER be inside of methods at all! Why isn't that a compiler error?!

    The debate is really based around this simple question:

    Is the average developer intelligent enough to handle the responsibility of having a given "feature?"

    Just defining the "average developer" is a predicament. Some would be offended by your suggestion to restrict the feature set because they're idiots and their the ones putting #region's in the middle of while loops. Others wouldn't care at all since there are plenty of other logical ways of organizing code. Some are both (like myself).

    I am all for the preservation of concepts (good and bad). Making development too easy for the newbie is going to make a nightmare down the road that I don't want to fix. It's best that they bang their heads against the wall for a month and learn how to use features more "appropriately" than what would result in a complete lack of discipline.

    ReplyDelete
  12. Thanks David! Good point. Love to know you read the whole thing using Google Translator. Now probably some people will have to reverse your comment using Google Translator too, but that's ok :)

    Regarding the compiler error when using regions inside methods, I'm all for it. I would even crash your entire operating system if you try to compile such code.

    ReplyDelete
  13. Bueno, bueno, le dijo la mula al freno!. Sobre el uso Regiones para agrupar Propiedades y Metodos creo recordar que alguna que otra vez me ha incomodado y me he tomado el trabajo de Eliminarlas.

    Yo no lo uso para nada, realmente no le veo mucha utilidad. Si tuviera alguna seria para temporalmente Contraer una parte del codigo y dejar visible solo lo que nos interesa y porque lo estoy comparando con otros archivos de codigo y necesito que me quede visual justo lo que necesito.

    Por poco comento que lo he usado para lo que planteo pero ahora recuerdo que ni siquiera eso porque lo que hice fue sencillamente contraer los metodos de forma que solo los nombres me quedaban visibles y quedaba abierto solo el codigo que me interesaba.

    Por lo demas, pues ni me frio ni calor. Los ignoro. Si alguien le ve un uso interesante pues no lo critico, que lo use y sea feliz.

    ReplyDelete
  14. Anonymous2/03/2011

    Bueno majos.
    Actualmente trabajo en un sistema que tiene un modelo de objetos de pelotas y como metodo de trabajo se ha establecido la politica de agrupar por este orden el codigo: Variables, Propiedades, Metodos (publicos, "amigables" y privados), Eventos e Implementaciones de Interfaces. En mi empresa no somos precisamente superfriquis de la programacion usando el notepad, y por tanto mi opinion es que no puede ser mas acertado. Me explico:
    usamos las #region como agrupacion y ordenacion, lo que se agradece, ya que si queremos buscar algo sabemos donde hay que ir exactamente ya que el codigo es de terceros (los compañeros en si) y no siempre sabemos como se llama lo que buscamos pero sí por donde anda. Y eso de que siempre hay que darle al +, no se en que te basas porque normalmente estan abiertas y el VS te guarda el estado, pero vamos puedes colapsar o expandir todo a tu gusto y darle a la ruedita media mañana. Lo que si no veo bien y estoy de acuerdo con todos es que las regiones dentro de metodos es una mala practica ademas de ser un claro error por parte del desarrollador pudiendo haberlo refactorizado en otros metodos que incluso alguno podrá reutilizar!!!

    ReplyDelete
  15. Digamos que es un problema de gustos, pero para mi opinión completamente innecesario. Sin necesidad de ninguna región el código puede ordenarse de esa misma forma que mencionas. Para encontrar un elemento de forma rápida hay múltiples vías, y te aseguro que todas son mucho más rápidas que abrir una región y luego buscar adentro.

    ReplyDelete

Note: Only a member of this blog may post a comment.