Reutilización de Javadoc para métodos sobrecargados

5 minutos de lectura

avatar de usuario
skrebel

Estoy desarrollando una API con muchos métodos con nombres idénticos que solo difieren en la firma, lo que supongo que es bastante común. Todos hacen lo mismo, excepto que inicializan varios valores por defecto si el usuario no quiere especificar. Como un ejemplo digerible, considere

public interface Forest
{
  public Tree addTree();

  public Tree addTree(int amountOfLeaves);

  public Tree addTree(int amountOfLeaves, Fruit fruitType);

  public Tree addTree(int amountOfLeaves, int height);

  public Tree addTree(int amountOfLeaves, Fruit fruitType, int height);
}

La acción esencial realizada por todos estos métodos es la misma; un árbol está plantado en el bosque. Hay muchas cosas importantes que los usuarios de mi API deben saber acerca de cómo agregar árboles para todos estos métodos.

Idealmente, me gustaría escribir un bloque Javadoc que sea utilizado por todos los métodos:

  /**
   * Plants a new tree in the forest. Please note that it may take
   * up to 30 years for the tree to be fully grown.
   *
   * @param amountOfLeaves desired amount of leaves. Actual amount of
   * leaves at maturity may differ by up to 10%.
   * @param fruitType the desired type of fruit to be grown. No warranties
   * are given with respect to flavour.
   * @param height desired hight in centimeters. Actual hight may differ by
   * up to 15%.
   */

En mi imaginación, una herramienta podría elegir mágicamente cuál de los @params se aplica a cada uno de los métodos y, por lo tanto, generar buenos documentos para todos los métodos a la vez.

Con Javadoc, si lo entiendo correctamente, todo lo que puedo hacer es esencialmente copiar y pegar el mismo bloque de javadoc cinco veces, con solo una lista de parámetros ligeramente diferente para cada método. Esto me parece engorroso y también es difícil de mantener.

¿Hay alguna forma de evitar eso? ¿Alguna extensión para javadoc que tenga este tipo de soporte? ¿O hay una buena razón por la que esto no es compatible que me perdí?

  • Gran pregunta y excelente descripción, gracias.

    – Josué Pinter

    11 de enero de 2014 a las 6:05

  • El mantenedor de LWJGL 3 escribió su propio postprocesador para contraer la documentación de campos y métodos similares, consulte salida generada. Esto es probablemente demasiado específico (y también demasiado frágil) para ser reutilizado por otros proyectos, pero no obstante puede ser interesante.

    – Marcono1234

    26 de enero a las 21:43


avatar de usuario
Sean Owen

No conozco ningún soporte, pero haría un javadoc completo con el método con la mayoría de los argumentos, y luego me referiría a él en otro javadoc como ese. Creo que es lo suficientemente claro y evita la redundancia.

/**
 * {@code fruitType} defaults to {@link FruitType#Banana}.
 *
 * @see Forest#addTree(int, Fruit, int)
 */

  • Extraño, esto funciona cuando hago referencia al método desde un archivo diferente, pero no desde el mismo archivo (en Eclipse 4.7 en Mac), lo cual es una molestia cuando intenta desaprobar una sobrecarga y señalar a las personas que llaman a una no obsoleta sobrecarga.

    – Sridhar Sarnobat

    3 de noviembre de 2017 a las 19:39


  • @Sridhar-Sarnobat: Desde dentro del mismo archivo debería ser @see #addTree(int, Fruit, int) (Sin el Forest)

    – Pato mugido

    31 de agosto de 2018 a las 20:44


  • Eclipse no me permite hacer clic en el método para llevarme al que se hace referencia 🙁

    – Sridhar Sarnobat

    24/09/2018 a las 18:02

  • Me gusta esta respuesta, pero ¿cómo se pueden deshabilitar las advertencias de JavaDoc que dicen “Advertencia: advertencia: no @param for x”?

    – z32a7ul

    13 de julio a las 18:33

avatar de usuario
Trineo

Simplemente documentaría su método “más completo” (en este caso addTree(int,Fruit,int) ) y luego en JavaDoc para otros métodos, consulte este y explique cómo/qué valores predeterminados se usan para los argumentos no proporcionados.

/**
 * Works just like {@link ThisClass#myPow(double,double)} except the exponent is always 
 * presumed to be 2. 
 *
 * @see ThisClass#myPow(double,double)
 */
 static double myPow( double base );

  • Desafortunadamente, eso se desmorona un poco cuando tienes un solo argumento de diferentes tipos.

    – Manio

    2 oct 2021 a las 17:57

avatar de usuario
Ciro Santilli Путлер Капут 六四事

Es probable que no exista un buen método estándar, ya que incluso el código fuente de JDK9 simplemente copia y pega grandes porciones de documentación, por ejemplo, en:

Se repiten 4 líneas de comentario. Vaya, no sequedad.

avatar de usuario
Brixomático

Ponga la documentación en la interfaz, si puede. Las clases que implementan la interfaz heredarán el javadoc.

interface X(){
 /** does fooish things */
 void foo();
}

class Ax implements X{ //automatically inherits the Javadoc of "X"
 @Override 
 public void foo(){/*...*/} 
}

En caso de que desee heredar la documentación y agregarle sus propias cosas, puede usar {@inheritDoc}:

class Bx implements X{
 /**
  * {@inheritDoc}
  * May fail with a RuntimeException, if the machine is too foo to be true.
  */
 @Override 
 public void foo(){/*...*/}
}

Ver también:
http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/javadoc.html#inheritingcomments

Ahora, como entendí, esto no es exactamente lo que desea (desea evitar repeticiones entre los métodos en la misma clase/interfaz). Para esto, puede usar @see o @link, como lo describen otros, o puede pensar en su diseño. Tal vez le gustaría evitar sobrecargar el método y usar un solo método con un objeto de parámetro en su lugar, así:

public Tree addTree(TreeParams p);

Para ser usado así:

forest.addTree(new TreeParams().with(Fruits.APPLE).withLeaves(1500).withHeight(5));

Es posible que desee echar un vistazo a este patrón de copia-mutador aquí:

https://brixomatic.wordpress.com/2010/03/10/dealing-with-immutability-and-long-constructors-in-a-fluent-way/

Dependiendo de la cantidad de combinaciones de parámetros, esta podría ser la forma más fácil y limpia, ya que Params-Class podría capturar los valores predeterminados y tener un javadoc para cada parámetro.

¿Ha sido útil esta solución?