Creo que en realidad son dos preguntas en una: intentaré responder a ambas.
1) ¿Cómo reducimos el código duplicado en una base de código?
Ayuda a recordarnos el beneficio de hacer esto: da como resultado menos errores debido a la lógica comercial duplicada y se necesita mantener menos código. La mejor manera de evitar que esto suceda es a través de la comunicación, como se menciona en las otras respuestas. Estoy totalmente de acuerdo con la recomendación de usar revisiones de código con la advertencia adicional de que debe compartir las responsabilidades de revisión de código por igual para difundir adecuadamente el conocimiento. También debe usar stand-ups diarios para que los desarrolladores a menudo reconozcan cuando alguien está tratando de resolver un problema para el que existe un código útil existente. También debe considerar el emparejamiento de código, ya que aumenta el intercambio de conocimientos y ayuda a mantener a los programadores disciplinados.
También recomendaría que sus desarrolladores estén lo más cerca posible, preferiblemente en la misma habitación. Con muchas pizarras y espacios compartidos. Luego envíelos a comer juntos. Cuanto más se "unan" sus desarrolladores, mejor se comunicarán entre sí.
No estoy de acuerdo con la recomendación de usar un wiki o similar al código del documento. No importa cuán disciplinados sean los desarrolladores, la documentación se derivará del código original. Un enfoque más efectivo sería el uso de la especificación mediante pruebas de estilo de ejemplo. Estos documentan el código de una manera que deja en claro cómo debe usarse y sus pruebas fallarán si alguien cambia el código sin cambiar los ejemplos.
Ya tiene una gran base de código con muchos códigos duplicados, por lo que probablemente debería trabajar para refactorizar esto. Puede ser difícil encontrar código duplicado que no haya sido cortado y pegado. Entonces, en lugar de hacerlo, le sugiero que analice su historial de cambios. Busque archivos que a menudo cambian al mismo tiempo. Esto probablemente indicará problemas con la encapsulación si no indica un código duplicado real y vale la pena limpiar de todos modos. Si también puede analizar su historial de corrección de errores en relación con los cambios en su código, puede encontrar puntos de acceso específicos donde las correcciones son a menudo necesarias. Analice estos puntos de acceso y probablemente encontrará que muchos de ellos se deben a una lógica comercial duplicada que un desarrollador solo ha cambiado en un lugar sin darse cuenta de que necesita cambiar dos veces.
2) ¿Cómo debemos enfocarnos en hacer widgets, componentes, bibliotecas, etc. compartidos que luego puedan usarse en otros proyectos ?
En este caso, no debería intentar ajustar la lógica de negocios, sino compartir código de marco útil. Esto puede ser un equilibrio complicado ya que el costo de crear y mantener un conjunto de componentes compartidos puede ser bastante grande y puede ser difícil predecir en qué casos vale la pena hacerlo. El enfoque que sugeriría aquí es una regla de tres strikes. No se preocupe por escribir un código similar dos veces, pero cuando necesite hacerlo por tercera vez, refactorícelo en un componente compartido. En este punto, puede estar razonablemente seguro de que será útil y tiene una buena idea de los requisitos más amplios para el componente. Obviamente, la comunicación entre desarrolladores es vital aquí.
Considere crear la mayor cantidad posible de código abierto de sus componentes compartidos. No es una lógica de negocios, por lo que no le dará a sus competidores muchas ventajas, pero significa que obtendrá revisores y mantenedores adicionales de forma gratuita.