¿Qué técnicas utilizas para maximizar la reutilización del código?

StackOverflow https://stackoverflow.com/questions/145720

  •  02-07-2019
  •  | 
  •  

Pregunta

Hace algunos años me dijeron sobre un estudio sobre la reutilización de código. Aparentemente se descubrió que, en promedio, los programadores tienen una ventana de 7 minutos cuando buscan código para reutilizar. Si no encuentran código que se adapte a sus necesidades dentro de esa ventana, escribirán el suyo.

Esto se presentó en el contexto de la necesidad de administrar cuidadosamente su código para su reutilización para garantizar que pueda encontrar lo que necesita dentro de la ventana.

¿Cómo gestiona usted (las personas y las organizaciones) su fuente para facilitar su reutilización? ¿Mantiene específicamente una biblioteca de reutilización? Y si es así, ¿cómo lo indexa para maximizar su índice de aciertos?

¿Fue útil?

Solución

Una pregunta compleja:

  • Algunas partes del código pueden generalizarse como bibliotecas o API. Tenemos una biblioteca común que se mantiene actualizada con soluciones a problemas comunes. Típicamente: validación, almacenamiento en caché, clases de acceso a datos, registro, etc. ...

  • Algunas partes son específicas de la aplicación. No se pueden generalizar fácilmente. Los convertimos en HowTos y hacemos presentaciones internas. El código también se recicla mediante el uso de un SCM fácilmente navegable (en nuestro caso SVN).

  • También tenemos herramientas que generan código que, por un lado, no se puede reciclar, por otro siempre es similar (piense en llamar a un procedimiento almacenado).

  • La programación de pares también es una forma útil de difundir el conocimiento de las soluciones existentes. Usamos eso cuando es posible o apropiado.

  • La última técnica es la matrícula. Cada codificador tiene un tutor para consultar. Como los tutores son pocos, se comparte mucho entre ellos y este conocimiento se puede difundir de arriba hacia abajo.

Otros consejos

Refactorice sin piedad y espere lo mejor.

Actualización (4 años después y con suerte más sabia)

  • Al igual que el comentario de S.Lott dice: Presta atención a los nombres. Corre la voz a todos los 'committers' en el equipo. Los buenos nombres hacen que las cosas se puedan buscar y, por lo tanto, reducen la duplicación.
  • Tenga UNA forma de hacer algo y manténgalo ACCESIBLE y BÚSQUEDA.
  • Escriba el código para el programador promedio (L.C.D.). No sea inteligente donde lo suficiente sería suficiente. (Eso incluye la compulsión del diseño del calzado y los trastornos relacionados)
  • Adopte un conjunto común de convenciones, estilos, pautas, estándares, etc. todo desde el principio. Garantizar la aceptación y, por lo tanto, el cumplimiento dentro del equipo. (¡Esto significa que todos usan las pestañas (o espacios)!). No importa lo que elija, el objetivo es que el código se vea coherente
  • Tener un guardián (respetado por el equipo), que observa todos los registros para detectar banderas rojas.
  • Escribir código test-first / outside-in. Esto generalmente asegura que su código sea utilizable por múltiples clientes. (Ver la viñeta del GOOS sobre independencia de contexto)
  • Tener un marco de trabajo que sea compatible activamente.

  • Conozca la base de código existente / haga que los otros desarrolladores conozcan la base de código. Si su grupo / empresa es lo suficientemente grande, busque a alguien que conozca la base del código y se le pueda pedir orientación.

  • Documento, documento, documento. El código no documentado es inútil para su reutilización porque lleva demasiado tiempo comprender su funcionamiento interno.

  • Tener buenas interfaces. Tipos fáciles, estructuras o clases fáciles. Cuanto más complicado es algo, menos se usará en otro proyecto.

  • Optimiza y depura el código reutilizable. Los desarrolladores que experimentan errores en el código de otras personas por enésima vez comenzarán a codificar nuevamente el código ya existente.

Intente usar TDD si todavía no es mi respuesta inicial.

Creo que el uso de TDD es una excelente manera de mantener bajo el acoplamiento de código, entre otros beneficios. Si bien eso no impide que el mismo comportamiento se implemente dos veces, hace que sea mucho más fácil identificar un área en la que podría eliminar la duplicación.

Otro beneficio, TDD tiene un paso para eliminar la duplicación (refactorización) como parte del ciclo.

Además, las pruebas forman parte de la documentación de sus códigos, lo que facilita la identificación de comportamientos duplicados.

La organización es la clave. Si los espacios de nombres y el intellisense están disponibles, la función correcta se puede reducir y eventualmente encontrar. Si no encuentran exactamente lo que quieren, pueden encontrar algo cercano o relacionado. El código que se combina en un solo grupo enorme lo hace fácil de encontrar, pero las personas nunca encontrarán el método que desean lo suficientemente rápido.

La consistencia también es crítica, tanto con los nombres como con la ubicación. Si decide cambiar su estilo en algún momento durante el proyecto, regrese y cambie todo para adaptarlo a ese estilo. Fácilmente puede ser un proceso muy largo y aburrido, pero es mejor que intentar usar una biblioteca inconsistente.

Perfile toda la aplicación y comience a refactorizar desde la sección más pesada del código. (80% del tiempo dedicado al 20% del código más utilizado)

Use una herramienta de creación de perfiles que tenga la capacidad de identificar pérdidas de memoria, llamadas repetidas, llamadas largas, memoria no liberada, recursos no expuestos, etc.,

Por regla general, el nuevo código siempre utiliza las mejores prácticas.

How do you (individuals and organisations) manage your source to make it easier to reuse? Do you specifically maintain a reuse library? And if so, how do you index it to maximise your hit rate?

I don't and I have an admittedly controversial opinion here but I find the idea of maximizing code reuse counter-productive (I'm interpreting "maximizing" as prioritizing it above all other things rather than considering it as having both pros and cons to balance in consideration). I prefer instead to allow a healthy amount of redundant efforts in teams to slide in favor of decoupling and isolating each developer's module better. First before everyone starts disagreeing with me left and right, I think we can agree upon some things:

  1. Reusing buggy code that will have you spending hours debugging other people's code is not desirable.
  2. Reusing code that balances such a wide range of disparate needs that it barely satisfies your own needs and requires you to jump through a lot of hoops to ultimately get an awkward and inefficient solution is undesirable.
  3. Reusing code that constantly requires design changes and goes through deprecations of a kind which will require you to rewrite the code using it every 6 months is undesirable if you could have just implemented the solution yourself in half an hour in ways that don't need design changes in the future since it's only serving your precise needs.
  4. A codebase filled with alien-looking code is undesirable over one that uses more of the language and standard library in idiomatic and familiar ways, even if that requires slightly more code.
  5. Developers stepping all over each other's toes because both of them want to make incompatible changes to the same design while fighting and arguing and making changes which cause bugs in each other's implementations is undesirable.
  6. Throwing a boatload of dependencies to immature designs that have not proven themselves (not had thorough test coverage, not had the time to really soundproof the design and make sure it effectively satisfies user-end needs without requiring further design changes) is undesirable.
  7. Having to include/import/link a boatload of libraries and classes/functions with the most complex build script to write something simple is undesirable.
  8. Most of all, reusing code in a way that costs far more time both in the short and long run than not reusing it is undesirable.

Hopefully we can at least agree on these points. The problem I've found with maximizing code reuse from overly-enthusiastic colleagues was that it often lead to one or more of the problems above. It wasn't directly the enthusiasm for code reuse that was the fundamental problem but that the priorities were skewed towards code reuse rather than test coverage, soundproofing designs, making sure things are mature enough before we reuse them like crazy, and so forth.

Naturally if all the code we reused worked beautifully, had thorough test coverage, was proven to fulfill the needs of everything using it in ways that were far more productive than not reusing it, and didn't have to go through any design changes for years on end, I would be ecstatic about code reuse. But my experiences often found things falling far short of this ideal in ways where code reuse was arguably becoming the maintenance problem rather than the solution.

How do you (individuals and organisations) manage your source to make it easier to reuse? Do you specifically maintain a reuse library? And if so, how do you index it to maximise your hit rate?

So, again I don't seek to "maximize" code reuse among proprietary code written internally among the team. I seek to make sure the team doesn't spend enormous amount of time on redundant effort, but I let things slide quite a bit if both the physicists and the rendering guys both implement their own axis-aligned bounding box class, e.g. It's not necessarily even that redundant, since the physicist might use min/max representations which are more efficient for his purpose while the rendering developer might use center/half-size representations. I do try to make sure we reuse as much of the standard library when possible, because that's code reuse of a kind that is practically guaranteed to be solid, ultra well-tested, and not require further design changes (other teams are spending a boatload of their time to make sure of that).

Instead I shift the focus on testing. A module duplicating a little bit of code here and there is totally fine if you ask me if it's working beautifully in ways that make users really happy, has thorough test coverage, and doesn't warrant endless changes. We accept such duplication all the time when we use third party libraries who likely duplicate some code that we also have in our internal codebase. It's not an issue there when the redundancy doesn't lead to redundant maintenance efforts.

So I suggest just relaxing the idea of maximizing code reuse just a little bit. But if you want to make it easy as possible to reuse the really solid, well-tested, non-trivial code, then I've found it far more helpful to organize very singular-purpose libraries, like a "math" library, an "image" processing library, etc. -- instead of trying to fuse them all together into something like "core" or "common". The latter types tend to tempt developers to throw in all kinds of eclectic utility functions which barely benefit the team using them, and mostly it tends to become messy in ways where it starts to become difficult to find anything of interest.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top