
La programación mediante copiar y pegar , a veces denominada simplemente pegar , consiste en la producción de código de programación altamente repetitivo mediante operaciones de copiar y pegar . Es principalmente un término peyorativo; quienes lo utilizan suelen implicar una falta de competencia en programación y de capacidad para crear abstracciones. También puede ser el resultado de limitaciones tecnológicas (por ejemplo, un entorno de desarrollo insuficientemente expresivo), ya que normalmente se utilizarían subrutinas o bibliotecas. Sin embargo, existen ocasiones en las que la programación mediante copiar y pegar se considera aceptable o necesaria, como para el código repetitivo , el desenrollado de bucles (cuando el compilador no lo admite automáticamente ), lenguajes con capacidades limitadas de metaprogramación o ciertos modismos de programación, y algunos editores de código fuente la admiten en forma de fragmentos de código .
Orígenes
La programación mediante copiar y pegar suele ser realizada por programadores inexpertos o estudiantes, a quienes les resulta difícil o irritante escribir código desde cero y prefieren buscar una solución preescrita o parcial que puedan usar como base para resolver sus propios problemas. [ 1 ] (Véase también Programación de culto al cargo )
Los programadores inexpertos que copian código a menudo no comprenden del todo el código preescrito que están utilizando. Por lo tanto, el problema surge más de su inexperiencia y falta de confianza en la programación que del acto de copiar y pegar en sí. El código suele provenir de diversas fuentes, como el código de amigos o compañeros de trabajo, foros de internet , proyectos de código abierto, código proporcionado por los profesores o ayudantes de cátedra, o libros de texto de informática . El resultado corre el riesgo de ser una mezcla incoherente de estilos y puede contener código superfluo que aborda problemas para los que ya no se requieren nuevas soluciones.
Otro problema es que pueden introducirse fácilmente errores debido a suposiciones y decisiones de diseño tomadas en los distintos archivos fuente que ya no son válidas cuando se colocan en un nuevo entorno.
Dicho código también puede, de hecho, estar ofuscado involuntariamente , ya que los nombres de las variables, clases, funciones y similares generalmente se dejan sin cambios, aunque su propósito puede ser completamente diferente en el nuevo contexto. [ 1 ]
La programación mediante copiar y pegar también puede ser consecuencia de una comprensión deficiente de características comunes en los lenguajes de programación, como las estructuras de bucles, las funciones y las subrutinas.
Duplicación

Aplicando el código de la biblioteca
Copiar y pegar también lo hacen los programadores experimentados, que a menudo tienen sus propias bibliotecas de fragmentos de código bien probados y listos para usar, y algoritmos genéricos que se adaptan fácilmente a tareas específicas. [ 2 ]
Al ser una forma de duplicación de código , la programación mediante copiar y pegar presenta algunos problemas intrínsecos; estos problemas se agravan si el código no conserva ningún vínculo semántico entre el texto original y las copias. En este caso, si se necesitan realizar cambios, se pierde tiempo buscando todas las ubicaciones duplicadas. (Esto puede mitigarse parcialmente si el código original y/o la copia están debidamente comentados; sin embargo, incluso así, persiste el problema de realizar las mismas ediciones varias veces. Además, dado que el mantenimiento del código a menudo omite la actualización de los comentarios, [ 3 ] los comentarios que describen dónde encontrar fragmentos de código remotos suelen quedar obsoletos).
Los defensores de las metodologías orientadas a objetos se oponen además al uso de copiar y pegar en las "bibliotecas de código". En lugar de crear múltiples copias modificadas de un algoritmo genérico, un enfoque orientado a objetos abstraería el algoritmo en una clase encapsulada reutilizable . La clase se escribe de forma flexible, con soporte completo para herencia y sobrecarga , de modo que todo el código que la llama pueda interactuar para usar este código genérico directamente, en lugar de modificar el original. [ 4 ] A medida que se requiere funcionalidad adicional, la biblioteca se extiende (manteniendo la compatibilidad con versiones anteriores ). De esta manera, si el algoritmo original tiene un error que corregir o puede mejorarse, todo el software que lo utiliza se beneficia. La programación genérica proporciona herramientas adicionales para crear abstracciones.
Código de ramificación
La ramificación del código es una práctica habitual en el desarrollo de software en equipos grandes, ya que permite el desarrollo paralelo en ambas ramas y, por lo tanto, ciclos de desarrollo más cortos. La ramificación clásica presenta las siguientes características:
- Se gestiona mediante un sistema de control de versiones que admite ramificación.
- Las ramas se vuelven a fusionar una vez que se completa el desarrollo en paralelo.
La función de copiar y pegar es una alternativa menos formal a la ramificación clásica, que se utiliza a menudo cuando se prevé que las ramas divergirán cada vez más con el tiempo, como cuando se crea un nuevo producto a partir de uno ya existente.
Como método para lanzar un nuevo producto, la programación mediante copiar y pegar tiene algunas ventajas. Porque la nueva iniciativa de desarrollo no toca el código del producto existente:
- No es necesario realizar pruebas de regresión al producto existente, lo que ahorra tiempo de control de calidad asociado al lanzamiento del nuevo producto y reduce el tiempo de comercialización .
- No existe riesgo de que se introduzcan errores en el producto existente que puedan molestar a los usuarios ya instalados.
Las desventajas son:
- Si el nuevo producto no se diferencia tanto como se esperaba del producto existente, podría ser necesario mantener dos bases de código (con el doble de coste) en lugar de una sola. Esto puede conllevar costosos procesos de refactorización y fusión manual en el futuro.
- La duplicación del código base duplica el tiempo necesario para implementar los cambios que se deseen en ambos productos; esto aumenta el tiempo de comercialización de dichos cambios y, de hecho, puede anular cualquier ahorro de tiempo logrado al ramificar el código inicialmente.
De forma similar a lo anterior, la alternativa a un enfoque de copiar y pegar sería un enfoque modularizado:
- Empiece por extraer el código que compartirán ambos productos y organizarlo en bibliotecas.
- Utilice esas bibliotecas (en lugar de una segunda copia del código fuente) como base para el desarrollo del nuevo producto.
- Si se prevé una tercera, cuarta o quinta versión adicional del producto en el futuro, este enfoque es mucho más sólido, porque las bibliotecas de código prefabricadas acortan drásticamente el ciclo de vida de desarrollo para cualquier producto adicional después del segundo. [ 5 ]
Tareas repetitivas o variaciones de una tarea

Una de las formas más dañinas de programación mediante copiar y pegar se produce en código que realiza una tarea repetitiva, o variaciones de la misma tarea básica dependiendo de alguna variable. Cada instancia se copia de arriba y se vuelve a pegar, con pequeñas modificaciones. Entre los efectos nocivos se incluyen:
- El método de copiar y pegar a menudo da como resultado métodos extensos (un mal olor de código ).
- Cada instancia crea un duplicado de código, con todos los problemas analizados en secciones anteriores, pero con un alcance mucho mayor. Es común encontrar decenas de duplicados; cientos son posibles. En este tipo de código, la corrección de errores, en particular, se vuelve muy difícil y costosa. [ 6 ]
- Este tipo de código también presenta importantes problemas de legibilidad, debido a la dificultad de discernir con exactitud las diferencias entre cada repetición. Esto repercute directamente en los riesgos y costes de su revisión.
- El modelo de programación procedimental desaconseja encarecidamente el método de copiar y pegar para tareas repetitivas. En este modelo, se recomienda crear una función o subrutina que ejecute la tarea una sola vez; esta subrutina es llamada por la rutina principal, ya sea de forma repetitiva o, mejor aún, mediante algún tipo de estructura de bucle. Este código se denomina "bien descompuesto" y se recomienda por ser más fácil de leer y más fácilmente extensible. [ 7 ]
- La regla general aplicable en este caso es " no te repitas ".
Elección de diseño deliberada
En ocasiones, la programación mediante copiar y pegar se acepta como una técnica válida. Esto se observa con mayor frecuencia en código repetitivo, como declaraciones de clases o la importación de bibliotecas estándar, o al utilizar una plantilla de código existente (con contenido vacío o funciones ficticias) como base para completar el código.
El uso de modismos de programación y patrones de diseño es similar a la programación mediante copiar y pegar, ya que también utiliza código formulado. En algunos casos, esto se puede expresar como un fragmento de código que se puede pegar cuando sea necesario, aunque a menudo simplemente se recuerda de memoria. En otros casos, los modismos no se pueden reducir a una plantilla de código. Sin embargo, en la mayoría de los casos, incluso si un modismo se puede reducir a código, este será lo suficientemente largo como para abstraerse en una función o lo suficientemente corto como para escribirse directamente.
El lenguaje de programación Subtext es un proyecto de investigación que busca "despenalizar" la función de copiar y pegar. Mediante este lenguaje, copiar y pegar se convierte en el modelo de interacción principal y, por lo tanto, no se considera un antipatrón .
Ejemplo
Un ejemplo sencillo es un bucle for , que podría expresarse como .for(inti=0;i!=n;++i){}
Un ejemplo de código que utilice dicho bucle for podría ser:
void foo ( int n ) { for ( int i = 0 ; i != n ; ++ i ) { /* cuerpo */ } }El código del bucle podría haberse generado mediante el siguiente fragmento (especificando tipos y nombres de variables):
for ( $type $loop_var = 0 ; $loop_var != $stop ; ++ $loop_var ) { /* cuerpo */ }Véase también
Referencias
- 1 2 Yarmish, Gavriel; Kopec, Danny (2007). "Revisiting Novice Programmers Errors" . ACM SIGCSE Bulletin . 39 (2). acm.org: 131– 137. doi : 10.1145/1272848.1272896 . S2CID 8854303. Recuperado el 4 de junio de 2008 .
- ↑ "Creación dinámica de páginas web ASP.NET en el código subyacente" . codeproject.com. 25 de abril de 2008. Consultado el 4 de junio de 2008 .
- ↑ Spinellis, Diomidis. "Guía para detectar código defectuoso" . InformIT.com . Consultado el 6 de junio de 2008 .
- ↑ Lewallen, Raymond. "4 principios fundamentales de la programación orientada a objetos" . codebetter.com. Archivado del original el 25 de noviembre de 2010. Consultado el 4 de junio de 2008 .
- ↑ Eriksen, Lisa. "Reutilización de código en el desarrollo de software orientado a objetos" (PDF) . Universidad Noruega de Ciencia y Tecnología, Departamento de Ciencias de la Computación e Información . Consultado el 29 de mayo de 2008 .
- ↑ Ashley Marsh. "Estándares de codificación: el camino hacia un código mantenible" . MAAN Softwares INC . Consultado el 10 de abril de 2018 .
- ↑ "Universidad de Stanford, CS 106X ("Abstracciones de programación") Material del curso: "Descomposición"" (PDF) . Universidad de Stanford. Archivado del original (PDF) el 16 de mayo de 2008. Recuperado el 4 de junio de 2008 .
Enlaces externos
- c2: Programación de copiar y pegar
- Andrey Karpov. Consecuencias del uso del método Copiar-Pegar en la programación C++ y cómo abordarlas.
- Andrey Karpov. El efecto de la última línea.
- Detector de copiar/pegar de PMD , CPD.
- Programación informática