Ponowne użycie Javadoc dla przeciążonych metod

82

Tworzę API z wieloma identycznie nazwanymi metodami, które różnią się tylko podpisem, co, jak sądzę, jest dość powszechne. Wszystkie robią to samo, z wyjątkiem tego, że domyślnie inicjują różne wartości, jeśli użytkownik nie chce ich określać. Jako przystępny przykład rozważ

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);
}

Zasadnicza czynność wykonywana przez wszystkie te metody jest taka sama; drzewo jest sadzone w lesie. Wiele ważnych rzeczy, które użytkownicy mojego API muszą wiedzieć o dodawaniu drzew wstrzymanych dla wszystkich tych metod.

Idealnie chciałbym napisać jeden blok Javadoc, który jest używany przez wszystkie metody:

  /**
   * 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%.
   */

W mojej wyobraźni narzędzie mogłoby magicznie wybrać, który z parametrów @params ma zastosowanie do każdej z metod, a tym samym wygenerować dobre dokumenty dla wszystkich metod naraz.

W Javadoc, jeśli dobrze rozumiem, wszystko, co mogę zrobić, to w zasadzie skopiować i wkleić ten sam blok javadoc pięć razy, z tylko nieznacznie różniącą się listą parametrów dla każdej metody. Wydaje mi się to kłopotliwe i trudne do utrzymania.

Czy można to obejść? Jakieś rozszerzenie javadoc, które ma tego rodzaju obsługę? A może istnieje dobry powód, dla którego to nie jest obsługiwane, a przegapiłem?

skrebbel
źródło
1
Świetne pytanie i świetnie opisane, dzięki.
Joshua Pinter,

Odpowiedzi:

75

Nie znam żadnego wsparcia, ale w pełni javadoc użyłbym metody z największą liczbą argumentów, a następnie odwołałbym się do niej w innym javadoc. Myślę, że jest wystarczająco jasny i pozwala uniknąć nadmiarowości.

/**
 * {@code fruitType} defaults to {@link FruitType#Banana}.
 *
 * @see Forest#addTree(int, Fruit, int)
 */
Sean Owen
źródło
Dziwne, to działa, gdy odwołuję się do metody z innego pliku, ale nie z tego samego pliku (w Eclipse 4.7 na Macu) - co jest uciążliwe, gdy próbujesz wycofać jedno przeciążenie i skierować wywołujące do pliku, który nie jest przestarzały przeciążać.
Sridhar Sarnobat
2
@ Sridhar-Sarnobat: Z tego samego pliku powinno to być @see #addTree(int, Fruit, int)(bez Forest)
Mooing Duck
Eclipse nie pozwala mi kliknąć metody, aby przenieść mnie do
wskazanej
15

Po prostu udokumentowałbym twoją "najpełniejszą" metodę (w tym przypadku addTree(int,Fruit,int)), a następnie w JavaDoc dla innych metod odnieś się do tej i wyjaśnij, w jaki sposób / które wartości domyślne są używane dla argumentów, które nie zostały podane.

/**
 * 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 );
Sanki
źródło
7

Prawdopodobnie nie ma dobrej standardowej metody, ponieważ nawet kod źródłowy JDK9 po prostu kopiuje wkleja duże fragmenty dokumentacji, np. Pod adresem:

Powtarzane są 4 wiersze komentarza. Yikes, non-DRYness.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
źródło
0

Jeśli możesz, umieść dokumentację w interfejsie. Klasy implementujące interfejs odziedziczą wtedy plik javadoc.

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

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

Jeśli chcesz odziedziczyć dokumentację i dodać do niej własne rzeczy, możesz użyć {@inheritDoc}:

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

Zobacz też: http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/javadoc.html#inheritingcomments

Teraz, jak zrozumiałem, nie jest to dokładnie to, czego chcesz (chcesz uniknąć powtórzeń wśród metod w tej samej klasie / interfejsie). W tym celu możesz użyć @see lub @link, zgodnie z opisem innych, lub możesz pomyśleć o swoim projekcie. Może chciałbyś uniknąć przeciążania metody i zamiast tego użyć pojedynczej metody z obiektem parametru, na przykład:

public Tree addTree(TreeParams p);

Do użycia w ten sposób:

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

Możesz rzucić okiem na ten wzorzec mutatora kopiującego tutaj:

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

W zależności od ilości kombinacji parametrów może to być łatwiejszy i bardziej przejrzysty sposób, ponieważ klasa Params może przechwytywać wartości domyślne i mieć javadoc dla każdego parametru.

Brixomatic
źródło