Javadoc Pros and cons analysis (from IBM)

Source: Internet
Author: User
Tags error handling include integer join range thread tostring valid
The ADO Java language uses an integrated approach to API documentation in accordance with the Javadoc annotation convention. The Javadoc tools can help generate good API documentation, but most Java API documentation is bad. Because it's part of the source code, the API's documentation responsibility ultimately falls to the engineer. In this article, Brian criticizes the current state of Java documentation Practice and provides some guidelines on how to write more useful Javadoc.

For most Java class libraries, Javadoc is the only document. Furthermore, many Java classes do not use Javadoc except for commercial software components. Although Javadoc is excellent as an API reference tool, it is a very bad way to understand how the class library is organized and how it should be used. And even with Javadoc, it usually contains only the most basic information about what the method has done, ignoring important features such as error handling, scope and scope of parameters and return values, thread safety, locking behavior, preconditions, post conditions, invariant conditions, or side effects.

Learning from Javadoc

For many Java tools, including most open source packages and most internally developed components, the reality is that almost all class libraries or components do not have valid documents, including Javadoc. This means that developers will learn to use tools from Javadoc, and we should consider organizing our Javadoc based on this reality. I often joke that one of the most important skills that Java programmers need now is to use Google and Javadoc skillfully to "reverse engineer" APIs that are poorly documented. This may be true, but it's not very funny.

Most Java packages have some kind of "root" object, which is the first object that must be created before any other objects within the tool are obtained. In JNDI, the root object is the context, and in JMS and JDBC, it is Connection. If someone tells you that the underlying object in JDBC is Connection and how to get the object, then you will most likely find how to create and execute Statement and how to iterate through the list of methods available in Javadoc from Javadoc. ResultSet. But how do you know that getting Connection is your first step? Javadoc organizes the classes in alphabetical order within the package, organizing the methods alphabetically in the class. Unfortunately, there is no magic "start Here" notation in Javadoc that takes the reader to the logical start of the browsing API.

Package description

The closest thing to the "Start Here" notation is the package description, but it is rarely used effectively. If you put the file package.html in a package with the source code, the standard Doclet places the contents of the generated package-summary.html file in the package together with the same list. Unfortunately, the standard doclet that generate the HTML documents that we are all familiar with do not make package descriptions easy to find. If you click a package in the upper left pane, this causes a list of methods in the lower-left pane, but does not produce a summary of packages in the main pane-you must click the package name in the lower left pane to view the summary. But it doesn't matter, after all, most packages don't have package descriptions.

The package file is an excellent place to place a "start Here" document that outlines what the package does, what the main summary is, and where to start browsing the package.

Class Document

In addition to package files, class-specific documents can also play an important role in helping users thoroughly understand new tools. The class document should of course include a description of what this particular class does, but it should also describe how the class is associated with other classes in the package, especially to identify any factory class associated with the class. For example, the Statement class document in JDBC should indicate that Statement is obtained through the createstatement () method of the Connection class. In this way, if a new user accidentally enters the Statement page, he will find that first he needs to get Connection. A package that applies this convention to each class quickly points the root object to the user so that the user can be handy.

Because Javadoc is designed around documenting a particular class, there is usually no obvious place in Javadoc to place sample code that demonstrates the use of several related classes. But with a focus on the documentation of a particular class or method, we lose the opportunity to discuss how to combine the contents of the package. If you have a simple code example in the package document or class document that demonstrates some basic usage for the root object, it will be useful for many users. For example, a Connection class document can have a simple example that gets a connection, creates a precompiled statement, executes the statement, and iterates over the result set. Technically, this may not be part of the Connection page, as it also describes the other classes in the package. However, especially when combining the techniques above that refer to the classes on which the current class relies, users can quickly find ways to get a simple, practical example, regardless of how the class is organized.

Bad document = = bad Code

For most Java class libraries, there is no Javadoc, or very bad, except for those commercial products that are sold as packaged components. Because the fact is that Javadoc is the only document we have for most packages, it basically means getting ourselves into the predicament of not using most of our code except the author--or at least, without a major "archaeological" effort.

Since the document is now part of the code, I think it is time for the software engineering community to develop a consensus that, even if the code is excellent, if the document is bad, it should be considered bad code because it cannot be reused effectively. Unit testing has not been a good reputation until recently, it has been favored by many engineers, just as it is, in order to improve the reliability and reusability of the software we produce, API documentation must also be an integral part of the development process.

Writing Javadoc is some sort of code check

Writing reasonable Javadoc can also have side effects, forcing us to do some form of code checking to examine the architecture of classes and the relationships between them. If a single package, class, or method is difficult to document, you might try to document multiple packages, classes, or methods at the same time, which should be a hint that it might need to be redesigned.

The self-examination aspect of the document makes it more important to write Javadoc as early as possible during the development process, and then check it periodically as the code is developed, rather than just wait for the code to complete and then write the document (if there is time left). The latter strategy is very common, and it drags the document to the end of the project, when scheduling is tight and developers are under a lot of pressure. The result is more common, the worthless document shown in Figure 1, which provides only "false documentation." What the user really needs is to understand how the class works, but the document does not provide any such information.

Listing 1. Typical, worthless Javadoc.

/**

* Represents a command history

*/

public class Commandhistory {

/**

* Get the command history for a given user

*/

public static commandhistory getcommandhistory (String user) {

. . .

}

}

So what does a good document contain?

The organizational techniques described above (referencing related classes or factory classes in class descriptions, as well as package overviews and code samples) are a good starting point for creating good documents. It helps new users learn about new tools using Javadoc.

But an overview of the architecture completes only half of the task. The other half explains in detail what the method does and does not do, under what conditions, and how they handle the error condition. Most Javadoc does not fully provide the information that is required, that is, the Javadoc that adequately describes the behavior of the method in the expected case, and the missing information includes:

Method how to handle error conditions or inappropriate input

How to pass an error condition back to the caller

Subclass of which particular exception may be thrown

Which values are valid for the input

Class invariant condition, method precondition, or method post condition

Side effects

Whether there are important joins between methods

Class handles how multiple threads access an instance at the same time.

The Javadoc Convention provides @param markup that enables us to document the meaning of a parameter in addition to being able to document its name and type. However, not all methods can well accept any value of the parameter. For example, although you can legitimately pass null values (NULL) to any method that gets an object parameter without violating the type-checking rule, not all methods work correctly when you pass in a null value. Javadoc should explicitly describe a valid argument range, and if it wants a parameter to be non-null, it should be described, and if it expects the parameter value to be within a range, such as a string of some length or an integer greater than 0, then it should be described as well. Not all methods carefully examine the validity of their parameters, the combination of which is a hazard, without a validation check or documentation on an acceptable input range.

Return code

Javadoc makes it easy to describe the meaning of return values, but as with method parameters, @return tags should include a detailed description of the range of values that might be returned. Does it return a null value for the return type of the object's value? Is the result restricted to a known or Non-negative collection for the return type of the integer value? Does any return code have a special meaning, such as returning 1 from Java.io.InputStream.read () to indicate a file terminator? Will the return code be used to indicate an error condition, such as a null value if a table entry cannot be found?

Abnormal

The throws clause of the standard Doclet replication method, but the Javadoc @throws tag should be more specific. For example, Nosuchfileexception is a subclass of IOException, but most of the methods in Java.io are only declared as throwing IOException. However, the method may throw nosuchfileexception independent of other IOException, which is a useful fact for the caller to understand-it should be included in Javadoc. You should also indicate the actual error conditions for throwing various exception classes so that the caller knows what corrective action to take when the given exception is thrown. You should use @throws tags to document each checked or unchecked exception that the method might throw, and to document the conditions that throw the exception.

Pre condition, post condition and invariant condition

Of course, you should document the effect of the method on the state of the object. However, you may need to develop a more detailed description of the method's precondition, post condition, and class invariant condition. A precondition is a constraint on the state of an object before the method is invoked; For example, the precondition for invoking Iterator.next () is Hasmore () as true. A post condition is a constraint on the state of an object after the method call completes, for example, after calling Add (), the List cannot be empty. An invariant condition is a constraint on the state of an object, which guarantees that the state is always true, such as collection.size () = Collection.toarray (). Length ().

The contract Design (design-by-contract) tool, such as Jcontract, allows you to use special annotations to specify preconditions, post conditions, and class invariant conditions, which then generate additional code to enforce these constraints. Whether or not you use tools to enforce these expectations, documenting these constraints allows users to know what they can do to safely use the class.

Side effects

Sometimes, the method can have other side effects in addition to changing the state of the object, the JVM, or the underlying computing platform. For example, all methods that perform I/O have side effects. Some side effects are harmless, such as the number of requests that are reserved for class processing. Other side effects can have a significant impact on program performance and correctness, such as modifying the state of the object passed to the method, or storing a copy of the reference to the object. Side effects such as modifying the state of related objects or storing references to objects passed as method parameters should be documented.

Method Join

A method join means that two methods in a class are interdependent and assume the behavior of the other. A common scenario in which a method join occurs is when a method uses the ToString method of the same class internally, and assumes that ToString will format the object state in a special way. If the class is already subclasses and the ToString method is overridden, the situation can cause problems, and another method can suddenly fail, unless it is also overridden. If your method relies on the implementation behavior of other methods, you need to document those dependencies. Also, if the class is subclass, you can rewrite the two methods in a consistent way so that subclasses can still function.

Thread Safety

One of the most important behaviors that should be documented is thread safety, which is almost never documented. Is this class thread-safe? If not, can you use synchronous encapsulation to make it thread safe? Do these synchronizations have to be associated with a particular pipe threads relative or are any of the enhancement that have been used? method to obtain a lock for objects that are visible outside the class?

Thread safety is not actually a binary property; thread safety has several identifiable levels. It is not always easy to document thread safety, or even to determine the level of thread safety. Failure to do so will lead to serious problems; using a non-thread-safe class in a concurrent application can cause sporadic failures that often occur until deployment (when the application is exposed for loading). and encapsulating additional locks around a class that is already thread-safe can affect performance and even cause deadlocks.

Josh Bloch provides useful taxonomies in his effective Java programming Language Guide (see Resources) for a class's thread-safety level documentation. Classes can be grouped into one of the following groups in descending order of thread safety: immutable, thread-safe, conditional thread-safe, thread-compatible, and thread-polarized.

This classification is an excellent framework for passing important information about class behavior in the context of concurrent access. It doesn't matter whether you use this taxonomy, but you should identify the level of thread security your class intends to display. I also suggest that if the method obtains a lock on an object that is visible outside the code of the class itself, you should also document it, even if it is only an "implementation detail", to assist in making global locking order (Global-lock-order) decisions and preventing deadlocks.

Conclusion

Documenting the behavior of a class is much more than just giving a line description of what each method does. Effective Javadoc should include a description of the following:

How classes relate to each other

How methods affect the state of an object

Method how to notify their callers of error conditions and what errors they might notice

How a class handles use in a multithreaded application

The parameter scope of the method and the range of its return value

In addition, poor documentation (or even worse, no documentation) can lead to good code that is not available or reusable. By spending some extra time on the document, you will avoid countless setbacks for your users (possibly yourself).



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.