En el pasado, utilizaba la forma estándar de agregar @Deprecated
anotaciones a los métodos API que se eliminarán en una versión posterior.
Ahora estoy preparando una versión principal para una biblioteca, con muchas partes de API eliminadas y renombradas.
Para facilitar la transición a los usuarios existentes, tal vez podría ser útil si la nueva versión de la biblioteca se puede utilizar junto con la versión anterior.
Ventajas
- Se puede implementar un cambio dinámico entre versiones
- las aplicaciones pueden retroceder a la versión anterior si se encuentran errores en la nueva versión (útil en la fase beta)
Para hacer esto, simplemente podría mover la nueva versión de la biblioteca a un nuevo paquete de com.mycompany.library
acom.mycompany.library.v2
¿Es esta una práctica común o hay otras recomendaciones para el uso en paralelo de las bibliotecas Java?
Antecedentes:
La biblioteca es un simple convertidor de documentos. Entonces, además de un método de conversión (entrada, salida), tiene muchas propiedades de configuración y algunos controladores de eventos. Si proporciono el uso en paralelo, los consumidores podrían instanciarlos y configurarlos dinámicamente:
if (useVersion2) {
com.mycompany.library.v2.Converter c = new com.mycompany.library.v2.Converter();
// configure and run
c.setOption(...);
c.convert(in, out);
} else {
com.mycompany.library.Converter c = new com.mycompany.library.Converter();
// configure and run
c.setOption(...);
c.convert(in, out);
}
(pregunta movida de /programming/37192945/ )
for a short time period
. Ambos sabemos lo que significa temporalmente en la ingeniería de software. No? ;-)@Deprecated
anotación a su código. Luego, en el lanzamiento, cuando las personas actualicen, verán que el código está en desuso y deberían cambiar. Después de eso, elimine el código todos juntos.Respuestas:
Este enfoque es bastante común. Permite una transición sin problemas a una nueva API y una evolución segura hacia nuevas implementaciones.
Por supuesto, el enfoque if / then, como lo destaca Laiv en su respuesta, tiene algunos inconvenientes. Es tedioso Es fácil olvidar o mezclar cosas. Idealmente, el uso de envoltorios, fábricas o adaptadores podría proporcionar algunas alternativas más agradables. Pero a menudo, cuanto más simple, mejor.
Martin Fowler y Pete Hogdson han teorizado recientemente sobre este tema en un excelente artículo en el que describen lo que llaman "patrones de alternancia de características". Puede interesarle las diferentes estrategias de implementación, como el uso de un "enrutador de alternar", y los escenarios de uso se describen en detalle.
Nota: personalmente no se me encuentra de alternancia de funciones. Viniendo del mundo de C ++, prefiero la alternativa fácil y robusta usando alias de espacio de nombres y cláusulas para elegir en tiempo de compilación la versión a usar. Pero es específico del idioma y, además, no permite la configuración dinámica a medida que la función alterna. Entonces, como se dijo, a veces, cuanto más simple, mejor ;-)
fuente
La biblioteca de actualización es un gran ejemplo para esto. No ha pasado mucho tiempo desde que introdujeron una versión estable 2 que es realmente buena, incluso si trajo algunas roturas.
Algunas de las cosas notables que hicieron fueron:
La nueva API tiene mucho valor y aborda muchas de las deficiencias de la versión anterior. Esto significa que su nueva API debe ser muy buena. No solo en términos de cómo funciona, sino que también hace que se vea agradable y fácil, si alguna vez fue un problema.
Se lanzó la versión beta para la nueva API, lo que permite a los usuarios conocer los cambios desde el principio e incluso proporcionar buenos comentarios.
La transición tampoco fue tan dolorosa. Introdujeron el número de versión en el nombre del paquete, lo que significa que algunos cambios solo requieren la modificación de las declaraciones de importación. Sí, algunas clases fueron eliminadas y otras introducidas, pero no se sintió demasiado drástica. Esto también depende de cómo el usuario haya organizado su base de código, que está parcialmente fuera del alcance del desarrollador de API.
Además, se prefieren las guías de migración. Retrofit, al ser una biblioteca popular, muchos artículos sobre esto están disponibles en línea.
fuente
No creo que la división de código
if/else
sea un buen enfoque.Piensa a largo plazo. ¿Qué vas a hacer con otras versiones? )
¿Cómo puede terminar el código de usuario a lo largo del tiempo?
Para versiones menores o revisiones, se espera mantener la compatibilidad. @Deprecated viene con un comentario pidiendo al desarrollador que no use ese código. También sugiere qué componente / método / clase debería usarse en su lugar. Finalmente, muchos de ellos informan que el código en desuso no será compatible con otras versiones. O puede que no sea compatible (todavía no lo saben).
Sin embargo, en las nuevas versiones (rediseño de cambios importantes) no tiene demasiado sentido mantener el código obsoleto porque dificulta el mantenimiento. El código heredado también puede verse afectado por los cambios realizados. Directamente o no.
También deja en claro el uso. Incluso si el código obsoleto está anotado.
Si su caso es un cambio o una renovación importante, preferiría alentar / obligar a los usuarios a pasar a la nueva función.
Si la nueva lib parece inestable, el usuario puede degradar la dependencia y mantenerla hasta que se resuelvan los nuevos errores de lib.
Como desarrollador, espero cambios de una versión a otra. Si decido usar el nuevo, acepto hacer frente a dichos cambios.
En el peor escenario, puedo volver al anterior.
No me basaría en expresiones como 'es temporal'. Porque todos sabemos cómo termina ...
En lugar de evitar que el usuario caiga en tales afirmaciones que terminan en un código difícil de leer y difícil de mantener
fuente