Javadoc-Wiederverwendung für überladene Methoden


81

Ich entwickle eine API mit vielen identisch benannten Methoden, die sich nur durch die Signatur unterscheiden, was meiner Meinung nach ziemlich häufig ist. Sie alle machen dasselbe, außer dass sie verschiedene Werte standardmäßig initialisieren, wenn der Benutzer dies nicht angeben möchte. Betrachten Sie als verdauliches Beispiel

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

Die wesentliche Aktion, die von all diesen Methoden ausgeführt wird, ist dieselbe. Im Wald wird ein Baum gepflanzt. Viele wichtige Dinge, die Benutzer meiner API über das Hinzufügen von Bäumen wissen müssen, halten für all diese Methoden.

Idealerweise möchte ich einen Javadoc-Block schreiben, der von allen Methoden verwendet wird:

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

In meiner Vorstellung könnte ein Tool auf magische Weise auswählen, welche der @ -Params für jede der Methoden gelten, und so gute Dokumente für alle Methoden gleichzeitig generieren.

Wenn ich es mit Javadoc richtig verstehe, kann ich im Wesentlichen nur fünf Mal denselben Javadoc-Block kopieren und einfügen, wobei für jede Methode nur eine geringfügig abweichende Parameterliste vorhanden ist. Das klingt für mich umständlich und ist auch schwer zu pflegen.

Gibt es einen Weg daran vorbei? Eine Erweiterung auf Javadoc, die diese Art von Unterstützung hat? Oder gibt es einen guten Grund, warum dies nicht unterstützt wird, den ich verpasst habe?


1
Tolle Frage und ausgezeichnet beschrieben, danke.
Joshua Pinter

Antworten:


75

Ich kenne keine Unterstützung, aber ich würde die Methode mit den meisten Argumenten vollständig javadocieren und dann in einem anderen javadoc wie diesem darauf verweisen. Ich denke, es ist ausreichend klar und vermeidet Redundanz.

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

Seltsamerweise funktioniert dies, wenn ich auf die Methode aus einer anderen Datei verweise, jedoch nicht aus derselben Datei (in Eclipse 4.7 auf Mac). Dies ist ein Problem, wenn Sie versuchen, eine Überlastung zu verwerfen und Anrufer auf eine nicht veraltete Datei zu verweisen Überlast.
Sridhar Sarnobat

2
@ Sridhar-Sarnobat: Aus der gleichen Datei sollte es nur @see #addTree(int, Fruit, int)(ohne die Forest) sein
Mooing Duck

Eclipse erlaubt mir nicht, auf die Methode zu klicken, um zu der referenzierten zu gelangen :(
Sridhar Sarnobat

14

Ich würde nur Ihre "vollständigste" Methode dokumentieren (in diesem Fall addTree(int,Fruit,int)) und dann im JavaDoc für andere Methoden auf diese verweisen und erklären, wie / welche Standardwerte für die nicht angegebenen Argumente verwendet werden.

/**
 * 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 );

7

0

Stellen Sie die Dokumentation auf die Benutzeroberfläche, wenn Sie können. Klassen, die die Schnittstelle implementieren, erben dann das Javadoc.

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

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

Wenn Sie die Dokumentation erben und Ihre eigenen Inhalte hinzufügen möchten, können Sie {@inheritDoc} verwenden:

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

Siehe auch: http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/javadoc.html#inheritingcomments

Wie ich verstanden habe, ist dies nicht genau das, was Sie wollen (Sie möchten Wiederholungen zwischen den Methoden in derselben Klasse / Schnittstelle vermeiden). Dazu können Sie @see oder @link verwenden, wie von anderen beschrieben, oder Sie können über Ihr Design nachdenken. Vielleicht möchten Sie eine Überladung der Methode vermeiden und stattdessen eine einzelne Methode mit einem Parameterobjekt verwenden, wie folgt:

public Tree addTree(TreeParams p);

So zu verwenden:

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

Vielleicht möchten Sie sich dieses Kopier-Mutator-Muster hier ansehen:

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

Abhängig von der Anzahl der Parameterkombinationen könnte dies der einfachere und sauberere Weg sein, da die Params-Klasse die Standardeinstellungen erfassen und für jeden Parameter ein Javadoc haben könnte.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.