2009-06-24 19 views
6

Tengo las siguientes API:Java ruptura API

public interface MyApi { 

    /** 
    * Performs some stuff. 
    * @throws MyException if condition C1 
    */ 
    public void method() throws MyException; 
} 

ahora estoy realizando la siguiente modificación en mi implementación de la API

public class MyApiImpl { 

    public void method() throws MyException { 
    if (C1) { 
     throw new MyException("c1 message"); 
    } 
    ... 
    } 
} 

se sustituye por:

public class MyApiImpl { 

    public void method() throws MyException { 
    if (C1) { 
     throw new MyException("c1 message"); 
    } else if (c2) { 
     throw new MyException("c2 message"); 
    } 
    ... 
    } 
} 

¿Te considerar esto como una rotura API?

El código del cliente aún se compilará, pero el contrato de método definido por el API javadoc ya no se respeta, ya que MyExcepiton es lanzado por una "nueva" condición.

Si solo se actualiza el archivo jar de la API, la aplicación del cliente seguirá funcionando pero, dependiendo de la forma en que los clientes capten la excepción, el comportamiento de la aplicación puede cambiar mucho.

¿Cuál es su punto de vista sobre eso?

Respuesta

7

Sí, está incumpliendo el contrato de la interfaz lanzando una excepción cuando C1 no se produce.

Como regla general, cuanto más vago es el contrato de interfaz, más fácil es no romper :) Si la interfaz no está definida en términos de un C1 explícito, pero en términos más generales, eso da mucho más flexibilidad.

6

Mi punto de vista es que no debe cambiar el contrato definido por la API en la documentación. Si necesita un nuevo comportamiento, debe a) a) crear un nuevo método que pueda ser llamado por el cliente que refleje este nuevo comportamiento, o b) discutir con el cliente la necesidad del cambio y informarlo.

Esto realmente puede ser en ambos sentidos, es entre usted y sus clientes cuál será su enfoque.

1

Depende en gran medida de qué es c2. ¿Está dentro de los límites lógicos del contrato preexistente? Si es así, estás cumpliendo el contrato lanzando una MyException. Si no es así, quizás necesite lanzar un nuevo tipo de excepción.

Debo señalar que no soy un gran admirador de las excepciones marcadas. En última instancia, obligar a alguien a lidiar con una excepción no necesariamente hace que su código sea mejor o más seguro (de hecho, puede tener el efecto opuesto, ya que pueden pasar desagradables excepciones espurias).

1

Yo diría "no", sin rotura de API, a menos que MyException sea una RuntimeException. Entonces es.

De todos modos, me subclase MiExcepción para la condición C2

Y ambas condiciones C1 y C2 debería ser en mi humilde opinión "excepcional", yo no haría un hábito de excepciones que lanzan

1

Es una rotura. Que la API sea impuesta por construcciones de lenguaje o simplemente documentada es irrelevante.

Si esta rotura causa un problema para el código del cliente es una pregunta diferente. Puede ser que esté reparando un defecto y necesite cubrir el estuche C2 de esta manera para repararlo. Desde ese punto de vista, los desarrolladores de código cliente pueden estar contentos de que hayas realizado este cambio (¡suponiendo que no estén trabajando actualmente en torno al defecto de tal forma que se rompa ante el cambio!)

1

Creo que el problema aquí es que usted hizo parte de su interfaz, las condiciones específicas de implementación. Si la condición "C1" fuera solo parte de su implementación, entonces podría simplemente haber creado una nueva implementación que arroje una excepción en "C1" o "C2" sin romper la interfaz.