¿Cómo pruebo o refuto que los "objetos de Dios" están mal?


56

Resumen del problema:

En pocas palabras, heredé una base de código y un equipo de desarrollo que no puedo reemplazar y el uso de God Objects es un gran problema. En el futuro, quiero que tengamos que volver a factorizar las cosas, pero me están haciendo retroceder los equipos que quieren hacer todo con God Objects "porque es más fácil" y esto significa que no se me permitiría volver a factorizar. Retrocedí citando mis años de experiencia en desarrollo, que soy el nuevo jefe que fue contratado para conocer estas cosas, etc., y también lo hizo el representante de ventas de cuentas de compañías offshore de terceros, y esto ahora está en el nivel ejecutivo y en mi reunión es mañana y quiero entrar con mucha munición técnica para defender las mejores prácticas porque siento que será más barato a largo plazo (y personalmente creo que eso es lo que le preocupa al tercero) para la compañía.

Mi problema es desde un nivel técnico, sé que es bueno a largo plazo, pero estoy teniendo problemas con el plazo ultracorto y el plazo de 6 meses, y aunque es algo que "sé", no puedo probarlo con referencias y recursos citados fuera de una persona (Robert C. Martin, también conocido como tío Bob), ya que eso es lo que se me pide que haga, ya que me han dicho que tengo datos de una persona y solo una persona (Robert C Martin) no es un argumento suficientemente bueno .

Pregunta:

¿Cuáles son algunos recursos que puedo citar directamente (Título, año de publicación, número de página, cita) por expertos bien conocidos en el campo que dicen explícitamente que este uso de Objetos / Clases / Sistemas "Dios" es malo (o bueno, ya que estamos buscando para la solución técnicamente más válida)?

Investigación que ya he hecho:

  1. Tengo varios libros aquí y he buscado en sus índices el uso de las palabras "objeto de dios" y "clase de dios". Descubrí que, curiosamente, casi nunca se usa y la copia del libro GoF que tengo, por ejemplo, nunca lo usa (al menos de acuerdo con el índice que tengo delante), pero lo he encontrado en los dos libros a continuación, pero quiero más Puedo usar.
  2. Revisé la página de Wikipedia para "God Object" y actualmente es un trozo con pocos enlaces de referencia, así que aunque personalmente estoy de acuerdo con lo que dice, no tiene mucho que pueda usar en un entorno donde la experiencia personal no se considera válida. El libro citado también se considera demasiado viejo para ser válido por las personas con las que estoy debatiendo estos puntos técnicos, ya que el argumento que hacen es que "alguna vez se pensó que era malo, pero nadie podía probarlo, y ahora el software moderno dice" dios "los objetos son buenos para usar". Personalmente, creo que esta afirmación es incorrecta, pero quiero demostrar la verdad, sea lo que sea.
  3. En los "Principios, patrones y prácticas ágiles de Robert C Martin en C #" (ISBN: 0-13-185725-8, tapa dura) donde en la página 266 dice "Todo el mundo sabe que las clases de Dios son una mala idea. No queremos concentrar toda la inteligencia de un sistema en un solo objeto o una sola función. Uno de los objetivos de OOD es la división y distribución del comportamiento en muchas clases y muchas funciones ". - Y luego continúa diciendo que a veces es mejor usar las Clases de Dios de todos modos a veces (citando microcontroladores como ejemplo).
  4. En la página 136 de Robert C Martin "Clean Code: A Handbook of Agile Software Craftsmanship" (Y solo esta página) habla de la "clase de Dios" y lo llama como un excelente ejemplo de una violación de la regla de "las clases deberían ser pequeñas" él usa para promover el Principio de responsabilidad única "a partir de la página 138.

El problema que tengo es que todas mis referencias y citas provienen de la misma persona (Robert C. Martin), y soy de la misma persona / fuente. Me dicen que debido a que él es solo una opinión, mi deseo de no usar "Clases de Dios" es inválido y no es aceptado como una práctica recomendada estándar en la industria del software. ¿Es esto cierto? ¿Estoy haciendo las cosas mal desde una perspectiva técnica al tratar de seguir las enseñanzas del tío Bob?

Objetos de Dios y programación y diseño orientados a objetos:

Cuanto más pienso en esto, más creo que esto es más algo que aprendes cuando estudias POO y nunca se menciona explícitamente; Está implícito en un buen diseño mi pensamiento (no dude en corregirme, por favor, como quiero aprender), el problema es que "sé" esto, pero no todos lo saben, así que en este caso no se considera un argumento válido porque Efectivamente lo llamo verdad universal cuando, de hecho, la mayoría de las personas lo ignoran estadísticamente ya que estadísticamente la mayoría de las personas no son programadores.

Conclusión:

No sé qué buscar para obtener los mejores resultados adicionales para citar, ya que están haciendo un reclamo técnico y quiero saber la verdad y poder probarlo con citas como un verdadero ingeniero / científico, incluso si Soy parcial contra los objetos divinos debido a mi experiencia personal con el código que los usó. Cualquier ayuda o citas serán muy apreciadas.


19
Pídales documentación de los objetos de Dios como buena práctica.
Don Roby

43
¡Huir! No quieres trabajar allí.
Don Roby

11
Defina su comprensión del "Objeto de Dios" y cómo se relaciona con su pregunta. Pasas 4 párrafos diciendo que God Class no es un término estándar en la literatura. Entonces, ¿por qué lo estás usando? Si usa términos estándar de la industria y puede mostrar cómo esos conceptos se aplican a su proyecto actual, entonces podría convencer a algunas personas de su punto. El uso de palabras inventadas en una reunión de negocios solo va a socavar su argumento. Existen términos estándar de la industria: usted no es la primera persona en ver una pesadilla de todo es global o de un solo objeto, o lo que sea que esté tratando de describir.
GlenPeterson

18
Te estás perdiendo el término "antipatrón". Hacer una búsqueda en Google de "antipattern de objeto de Dios" arroja toneladas de páginas sobre las razones por las que son malas.
Izkata

21
No deberías estar atacando al objeto dios sino a los problemas que crea. Como: tenemos un acoplamiento muy estrecho entre todo y un cambio en A también requiere cambios en B, C y D. Entonces, para ayudar contra eso, vamos a extraer clases. O: queremos que el código esté en un marco de prueba, y no podemos hacer eso, ¿qué vamos a hacer? Además, trate de evitar el uso del término "Dios", las personas no receptivas pensarán que está usando hiperboles.
Pieter B

Respuestas:


51

El caso para cualquier cambio de práctica se realiza identificando los puntos débiles creados por el diseño existente. Específicamente, debe identificar qué es más difícil de lo que debería ser debido al diseño existente, lo que es frágil, lo que se está rompiendo ahora, qué comportamientos no se pueden implementar de manera simple como resultado directo (o incluso algo indirecto) de la implementación actual, o, en algunos casos, cómo sufre el rendimiento, cuánto tiempo lleva poner al día a un nuevo miembro del equipo, etc.

En segundo lugar, el código de trabajo supera cualquier argumento sobre teoría o buen diseño. Esto es cierto incluso para códigos incorrectos, desafortunadamente. Por lo tanto, tendrá que proporcionar una mejor alternativa, lo que significa que usted, como defensor de mejores patrones y prácticas, necesitará refactorizar para obtener un mejor diseño. Encuentre un plano estrecho de estilo trazador-bala a través del diseño existente e implemente una solución que, tal vez, para la iteración uno, mantenga la implementación del objeto dios funcionando, pero difiera la implementación real del nuevo diseño. Luego, escriba un código que aproveche este nuevo diseño y muestre lo que gana debido a este cambio, ya sea rendimiento, facilidad de mantenimiento, características, corrección de errores o condiciones de carrera, o reducción de la carga cognitiva para el desarrollador.

A menudo es un desafío encontrar un área de superficie lo suficientemente pequeña para atacar en sistemas mal diseñados, puede llevar más tiempo del que le gustaría entregar algún valor inicial, y la recompensa inicial puede no ser tan impresionante para todos, pero también puede trabajar para encontrar algunos defensores de su nuevo enfoque si lo combina con los miembros del equipo que son al menos un poco comprensivos.

Lamentar el Objeto de Dios solo funciona cuando estás predicando al coro. Es una herramienta para nombrar un problema, y ​​solo funciona para resolverlo cuando tienes una audiencia receptiva que es mayor y está lo suficientemente motivada para hacer algo al respecto. Arreglar el objeto de Dios gana el argumento.

Dado que su preocupación inmediata parece ser la aceptación ejecutiva, creo que es mejor argumentar que reemplazar este código debe ser un objetivo estratégico y vincularlos con los objetivos comerciales de los que usted es responsable. Creo que puede argumentar que puede proporcionar alguna dirección técnica trabajando primero en un pico técnico sobre lo que cree que debe hacerse para reemplazarlo, preferiblemente involucrando recursos de una o dos personas técnicas que tienen reservas sobre el diseño actual.

Creo que has encontrado suficientes recursos para justificar tu argumento; las personas en tales reuniones solo prestarán atención al resumen de su investigación, y dejarán de escuchar después de que mencione dos o tres fuentes que lo corroboren. Inicialmente, su enfoque debe estar en lograr que la recompra solucione el problema que ve, no necesariamente demostrando que alguien más está equivocado o que usted tiene la razón. Este es un problema social, no lógico.

En un rol de liderazgo tecnológico, debe vincular cualquiera de sus iniciativas a los objetivos comerciales, por lo que lo más importante para presentar su caso a los ejecutivos es qué hará el trabajo para esos objetivos. Debido a que también se te considera el "chico nuevo", no puedes esperar que la gente deseche su trabajo o esperar que se alineen rápidamente; debe generar cierta confianza demostrando que puede cumplir. Como una preocupación a largo plazo, en un rol de liderazgo, también necesita aprender a enfocarse en los resultados, pero no necesariamente estar apegado a los detalles del resultado. Ahora está allí para proporcionar dirección estratégica, eliminar obstáculos tácticos del progreso de su equipo y ofrecerle orientación a su equipo, no ganar batallas de credibilidad con los miembros de su propio equipo.

Tomar una decisión de arriba hacia abajo rara vez será creíble a menos que tengas algo de máscara en el juego; Si se encuentra nuevamente en una situación similar, debe enfocarse más en la creación de consenso dentro de su organización en lugar de escalar una vez que sienta que la situación está fuera de control.

Pero teniendo en cuenta dónde se encuentra ahora, diría que su mejor opción es argumentar que su enfoque traerá beneficios medibles a largo plazo basados ​​en su experiencia y que está en línea con el trabajo de profesionales conocidos como el tío Bob y compañía. , y que le gustaría pasar unos días / semanas liderando con el ejemplo en una refactorización estrecha del aspecto más rentable, para demostrar cómo debería ser su visión del buen diseño. Sin embargo, deberá alinear cualquiera que sea su caso con objetivos comerciales específicos más allá de sus preferencias personales.


44
Buen punto sobre que es un problema social. Debe ser por qué hay tanto código escrito incorrecto y aplicaciones mal diseñadas por ahí.
Yanick Rochon

55
+1 por vincularlo con 'business speak' como tal; pretenda que sea lo más relevante posible para su audiencia. Si usted está hablando con ejecutivos continuación, hacer hablar de cómo el estándar de código tiene una relación directa con el mantenimiento y el rendimiento, y no discutir cómo esto se relaciona con las finanzas generales del proyecto, estabilidad a largo plazo y así sucesivamente. Parece que te han contratado por tu conocimiento; recuerda esto. (Simplemente no se convierta en un imbécil gerente que cree que él siempre sabe mejor , pero en este caso tiene el 100% de razón).
Fergus en Londres el

2
+1 para "código de trabajo triunfa sobre cualquier argumento sobre teoría o buen diseño". Algo que a menudo olvidamos en nuestra búsqueda del código perfecto.
Bjarke Freund-Hansen

Gran respuesta, mucha sabiduría para aspirantes a líderes de equipo.
jimmy_terra

24

Primero, debe presentar que cualquier organización medible debe adoptar las mejores prácticas de la industria. Diciendo que "¡simplemente funciona para nosotros!" no se puede medir, ni en el tiempo ni en los recursos, ya que es simplemente impredecible. La ingeniería de software es una ciencia tanto como cualquier otro campo de la ciencia, y estos conceptos han sido estudiados, investigados, probados y documentados.

  1. El Objeto de Dios es un antipatrón que establece que

    En ingeniería de software, un antipatrón (o antipatrón) es un patrón utilizado en operaciones sociales o comerciales o ingeniería de software que puede usarse comúnmente pero que es ineficaz y / o contraproducente en la práctica.

  2. En la conferencia Google IO de 2009 , este tema se explicó parcialmente cuando se explicó el patrón MVP. Puede que no sea relevante para el Objeto de Dios, pero puede darle algo de munición.

  3. Además, el uso de este antipatrón viola el principio de responsabilidad única en los diseños orientados a objetos, que establece que:

    cada clase debe tener una sola responsabilidad, y esa responsabilidad debe estar completamente encapsulada por la clase. Todos sus servicios deben estar estrechamente alineados con esa responsabilidad.

  4. El blog de Decaying Code también habla sobre esto y sobre su solución.

  5. No podemos hablar del principio de responsabilidad única sin hablar del acoplamiento de objetos .

    [...] acoplamiento o dependencia es el grado en que cada módulo del programa depende de cada uno de los otros módulos.

    Donde tener un sistema estrechamente acoplado puede causar assembly of modules [to] require more effort and/or time [to maintain] due to the increased inter-module dependency.un mayor nivel de acoplamiento de objetos significa menos cohesión, y viceversa. Los objetos de Dios son un buen ejemplo de acoplamiento estrecho, ya que saben más de lo que deberían, por lo que los sobrecargan de responsabilidad y limitan en gran medida la reutilización del código.

  6. Al diseñar una aplicación compleja, la simplicidad debe venir a la mente. Los grandes problemas deben descomponerse en otros más pequeños, que son más fáciles de administrar, probar y documentar. Esto es especialmente cierto en un paradigma orientado a objetos.

    Con este argumento, volvemos al argumento antipatrón, pero este paradigma se trata de patrones, representación de objetos del mundo real y, en última instancia, encapsulación de datos.

  7. Tiene razón cuando dice que estas "buenas prácticas" son más existentes en las aulas. Sin embargo, tengo experiencias docentes en la universidad (y en algunas universidades) y solo vi que estos principios se enseñaban en las universidades, especialmente en las facultades de ingeniería. Lo cual es triste Pero como cualquier buena práctica, aquellos que se esfuerzan por mejorar ellos mismos usualmente aprenden algunos patrones básicos de diseño y eventualmente entienden cómo sellar entre el acoplamiento y la cohesión.

    Lo que generalmente enseño a los estudiantes es que puede parecer que se requieren más esfuerzos para adoptar buenos estándares de programación, pero siempre vale la pena a largo plazo. Un buen ejemplo sería alguien pidiéndole a un programador que escriba una función de clasificación. El programador tiene dos opciones; 1) escriba una función de clasificación rápida de burbujas (menos de 5 minutos) que no será sostenible a medida que la lista de elementos crezca, o 2) escriba un algoritmo de clasificación más complejo (también conocido como optimizado) (clasificación rápida, etc.) que se escalará mejor con listas más grandes


1
Los lenguajes de programación orientados a objetos a menudo requieren que si dos conjuntos fuente independientes son responsables de diferentes aspectos del comportamiento de un objeto, se deberán crear instancias de objetos independientes para encapsular esos comportamientos. Desafortunadamente, aunque en muchos casos las subdivisiones más lógicas de funcionalidad entre ensambles de código no coinciden con la subdivisión más lógica de funcionalidad entre instancias de objetos, no he visto mucha discusión sobre cómo distinguir los dos tipos de subdivisión.
supercat

1
Creo que esto es un poco fuera de tema para esta pregunta. Aquí no estamos hablando del antipatrón del Objeto de Dios, sino del acoplamiento y la cohesión de código, que es un tema muy amplio y muy subjetivo.
Yanick Rochon

7

Ah, aquí voy, necroing otra vieja pregunta, pero voy a adivinar que no ganó este argumento y aquí está el por qué.

Suena como un problema cultural

Eres su gerente, pero no puedes reemplazarlos y tienes que ir a tus gerentes para que hagan lo que crees que deberían estar haciendo, en este caso, supongo que es al menos eliminarlo con el dios objetos que se mueven hacia adelante. A mí me parece un caso clásico de código que refleja la cultura en la que nació. En otras palabras, el objeto de Dios es cómo funciona esta empresa. ¿Quiere hacer algún tipo de cambio significativo? En última instancia, siempre irá al mismo lugar, ya que aparentemente todas las decisiones tienen que aclararse en la parte superior.

Habiendo tenido conocimiento de múltiples intentos fallidos de limpieza de código heredado y cambios en la política del código, ahora soy de la opinión de que no se puede luchar contra la cultura que hizo posible el código en primer lugar cuando esa cultura todavía está firmemente arraigada o, al menos, luchando La cultura es un trabajo duro cuesta arriba que es poco probable que alguien pueda pagarme lo suficiente o darme el poder suficiente para sentir que fue un esfuerzo que valió la pena y que probablemente tendría éxito nuevamente.

Antes de que pueda haber un cambio, tienen que estar motivados para cambiar y, desafortunadamente, como programadores que se preocupan por leer Stack de vez en cuando, es difícil para nosotros entender que no todos están motivados por lo mismo. He ganado muchos argumentos racionales en mis experiencias, pero al final del día la empresa sufre de desarrolladores intelectualmente perezosos por una razón.

Tal vez las preocupaciones comerciales se hayan motivado a pensar solo en el mañana en lugar de la próxima semana o dentro de cinco años (un escenario especialmente frustrante cuando eres hijo de inmigrantes de un país que construyó una bóveda de semillas en el Ártico en caso de apocalipsis). Tal vez tienen miedo al cambio. Tal vez valoran demasiado la antigüedad hasta el punto de que la cadena de mando no tiene sentido incluso cuando tienen que contratar desde el exterior para traer un líder o gerente de equipo de desarrollo porque reconocen que nadie en su equipo de toda la vida ha crecido lo suficiente en su tiempo allí (o porque dichas personas no quieren el riesgo asociado con la responsabilidad). O, y he visto esto, tal vez es el fenómeno muy real y deprimente de la mediocridad que se defiende a sí misma porque sabe en el fondo que puede '

¿Cómo combatir los problemas que en última instancia se basan en el miedo o en métricas rotas para el éxito? Te diré esto, se necesita mucho más que incluso un equipo de desarrollo de calidad comprometido y tenías mucho menos que eso por el sonido en el momento en que se publicó este Q.

En el caso no imposible de que no sea un problema cultural intratable ...

Ahora, suponiendo que las personas que están en la cima son muy receptivas al cambio, y en realidad están dispuestas a confiar en usted para que lo haga, realmente solo necesita puntuar todos sus argumentos con dinero y oportunidades perdidas.

Cada vez que lleva más tiempo entrenar a alguien nuevo en esta base de código ridícula, cada vez que lleva más tiempo modificar o agregar una nueva característica a algo, cada vez se vuelve prohibitivamente difícil exponer puntos finales a otro sistema de una compañía con la que desea asociarse , está costando dinero. Un montón de dinero maldito. Lo más importante es que deja una ventana abierta para que un competidor más pequeño y ágil se precipite, lo coloque en una posición donde todo lo que puede hacer es reaccionar a ellos demasiado lentamente y, finalmente, arrebatárselo todo.

Solo reconozca que una cultura particularmente terca y estúpida mantendrá el statu quo a toda costa, incluso si el techo físico real de la compañía está en llamas por eso.


3
Dejé la compañía poco después. trataron de contratarme a tiempo completo y hacerme mudar a Nueva York desde Seattle para aceptar la oferta; Básicamente les dije "De ninguna manera, no me mudaré a Nueva York cuando el equipo que estaría manejando esté en Bellevue, WA" y en ese momento básicamente crucé la calle y conseguí un trabajo en MSFT hasta que encontré algo mejor.
honestduane

1
@honestduane Sí, ese conjunto de expectativas solo dice mucho. Bien por ti en el GTFO.
Erik Reppen

3

Podría citar algunos de los principios más básicos de OOP, como acoplamiento flojo y alta cohesión. Un "objeto de Dios" parece que combina clases no relacionadas y tiene poca cohesión.


2

Siempre puedes preguntarle al tío Bob mismo.

La cuestión es que es tan obvio para las personas con algún sentido que, una vez que se explica, no es necesario que una multitud de autores vuelvan a hacer referencia a ella. Solo tiene que haber una fuente.

Otros términos con los que es posible que desee comenzar cuando busque fuentes son:

  • SÓLIDO
  • Ley de Demeter
  • Gran bola de barro

Todos estos conceptos expresos relacionados pueden generar fuentes de referencia viables, aunque en realidad no lo denominen como tal.

En última instancia, tú eres el jefe. La razón para hacerlo es porque usted lo dice, y aunque para ser considerado un buen gerente, realmente debe estar preparado para justificar sus decisiones; ya lo ha hecho, y si todavía hay resistencia, el curso de acción correcto es que su equipo haga lo que se le dice.


"si todavía hay resistencia, el curso de acción correcto es que su equipo haga lo que se les dice" ¿Quizás el curso de acción correcto es renunciar en lugar de hacer que su equipo se sienta miserable ...?
Tom

La decisión del gerente se ha justificado adecuadamente, y si el equipo no está de acuerdo, entonces el problema está en el equipo. El OP fue contratado por su experiencia y no se le permite usarlo para beneficiar al negocio porque los colegas no se comportarán razonablemente, no es aceptable. Cambiemos su afirmación: ¿por qué no deberían renunciar los miembros del equipo resistente si su visión del trabajo es incompatible con la del negocio?
Tom W

3
Punto justo. Depende de cómo quieras dirigir el equipo. Pero en mi experiencia, obligar a las personas a hacer cosas en contra de su voluntad solo conduce a la miseria. Prefiero ver God Objects en toda la base de código que un miserable equipo de desarrollo. Tal vez la respuesta es enviarlos a un curso de capacitación. Todo el mundo ama un curso de capacitación. Ganar-ganar
Tom

El desarrollador / gerente principal / lo que sea debe tomar absolutamente todas las medidas razonables para garantizar que el equipo mantenga una buena relación de trabajo entre sí. Si el entrenamiento adicional es útil, entonces considérelo como una opción, pero esto parece ser un caso de ignorancia voluntaria, y decirle a alguien que necesita capacitación para comprender su idea cuando lo que creen que han hecho no está de acuerdo. , en lugar de no entender, podría ser contraproducente. Me cuesta imaginar formas de tratar con personas que no quieren aprender.
Tom W

1

¿Cómo pruebo o refuto que los objetos de "dios" están mal?

No se puede.

Este tipo de conjetura no es susceptible de prueba matemática, y la prueba matemática es el único tipo de prueba que es sólida.

Incluso si intenta reemplazar la palabra emotiva "incorrecto" con medidas cuantificables de los efectos del uso de objetos divinos, encontrará que:

  1. las medidas disponibles son crudas,
  2. Existen pocos estudios creíbles en los que esas medidas se hayan cuantificado para el código producido por programadores profesionales.
  3. Hay pocos estudios creíbles, o ninguno, en los que las construcciones del lenguaje o los patrones de diseño (anti) se hayan vinculado a esas medidas.

Y eso es ignorar la cuestión de decidir cuándo un objeto en particular es un objeto "dios".

En el mejor de los casos, este tipo de estudio solo podría demostrar una correlación empírica. No es una prueba genuina.


Lo que realmente está haciendo es debatir los pros y los contras de los objetos de "dios" con el fin de cambiar las opiniones de otras personas ... y luego la práctica de su organización.

No use palabras como "prueba" o las personas con las que está debatiendo pueden reírse en su cara.


0

Es posible que desee ver al gurú de la semana # 84 . Se trata de objetos de Dios (monolitos) y de cómo son malos.

Extraer:

(Mayor) Aísla la funcionalidad potencialmente independiente dentro de una clase [...] (Menor) Puede desalentar extender la clase con nueva funcionalidad [...]


0

No estoy seguro si su equipo está realmente interesado en la prueba académica de que "Dios se equivoca".

Desde un punto de vista psicológico, su enfoque de refactorización puede malinterpretarse como atacar la competencia del equipo a la: "el equipo ha hecho un mal trabajo" aunque el programa funciona como se esperaba.

Lo que realmente quiere hacer es hacer frente a los efectos secundarios negativos del "código spagetti" y los "objetos de Dios": los costos de exploración para agregar nuevas características debido al aumento de errores causados ​​por los efectos secundarios.

Ser más específico y hacer preguntas en lugar de proporcionar respuestas puede ser más útil:

manager > Why did implement the new tax-calculation schema took more than 4 weeks
team > because {reason a}
manager > And why was {reason a}?
team > because {reason b}
manager > And why was {reason b}?
...
team > because {reason z}
manager > what could we do to avoid {reason z} ?
team > refactor code
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.