Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API

Newsletter sign-up

Sign up for our technology specific newsletters.

Enterprise Java
View all newsletters

Email Address:

Implement Design by Contract for Java using dynamic proxies

Write bug-free code with the DBCProxy framework

While developing software and its subsequent versions, developers often enhance functionality by modifying existing code. However, developers who modify or enhance that code are usually not its original authors. Depending on the complexity of code and its supporting documentation, and the clarity of requirements, enhancements may present a difficult problem.

For instance, suppose you could enhance an existing application by performing the following tasks: extend a class and override a method in the extended class. Questions arising during the design and implementation phase would most likely include: Should the super class method be called? If the super class method is called, should the overriding method call the super class method at the beginning or end of the overriding method?

Many developers experience this situation everyday as they maintain and enhance existing software. As a result, they are at the mercy of requirements specifications and existing software documentation to understand software's complexity. If either artifact is too vague, the developer may find designing and implementing the necessary changes difficult.

However, software that includes assertions, based on the Design by Contract (DBC) theory, combats that problem. You could clearly design and subsequently enhance that software because those assertions would advertise class, method, and interface contractual obligations. The assertions would provide a clear enforceable picture of the existing software's state, behavior, and interface. Thus, they make enhancing existing software much easier for developers.

In this article, I present a DBC for Java framework called DBCProxy. This framework uses dynamic proxy classes, which were introduced in Sun Microsystems's JDK 1.3. I'll begin by briefly introducing DBC, and then I'll describe DBCProxy's architecture and how you can use it in your development process.

Introducing DBC

When software developers perform object-oriented analysis and design (OOAD), they strive to identify appropriate abstractions within a problem domain. Additionally, they label these abstractions with a specific name and usually provide some additional text to further clarify it. In the software construction and implementation phase, developers utilize Java to transform these abstractions into Java interfaces, classes, and methods. These constructs let you advertise an abstraction's purpose and functionality.

Descriptive text and identifying names may offer a great deal of information about an abstraction. However, rarely do they provide a precise specification. Descriptive text may contain enough information to make it sound like a detailed specification, but plain text is often ambiguous and not enforceable.

DBC provides a formal way of writing detailed specifications with assertions; these can be viewed as enforceable contracts between the designer/developer of a class or interface (abstraction) and the class or interface client. To accomplish this, DBC uses three assertion types:

  • Preconditions: An object's valid state and the arguments passed to a method prior to a method call
  • Postconditions: An object's valid state and the arguments passed to a method after a method call
  • Class invariants: An object's valid state


When looking at contractual responsibilities, the client must satisfy the precondition prior to invoking a method. The supplier must satisfy the postcondition and class invariant. This clarifies the functionality provided and establishes an enforceable contract between a client and a supplier. Consequently, when a contract breaks (a software bug exists), you can easily tell whether the client or supplier did not satisfy its assertion(s). Also important to understand, DBC assertions are not part of the implementation. Rather, they are part of a class or interface specification. DBC clearly separates specification (what) from implementation (how). You can find additional information on DBC in Resources.

DBC in the development process

As software grows larger and more complex, the need to identify architectures and designs that satisfy such requirements as scalability, availability, security, and so on proves more important to the software's overall success. On large software projects, a team of software architects and software designers commonly specify an API for a subsystem and subsequently hand it off to a developer team to implement. The API specification is often ambiguous; in some cases, the architect or designer may interpret the specification differently than the implementer, which may introduce defects. Since DBC is assertions-based, it can help in these situations. Additionally, DBC possesses the following advantages:

  • Assertions communicate specifications clearly and precisely.
  • Class methods and interfaces are specified with assertions so architecture and design require more thought.
  • When the implementation doesn't satisfy assertions, assertion exceptions are thrown during software testing.
  • API users can begin implementation since DBC-based specifications clearly and precisely communicate what the client must do in a precondition. In addition, the API specification communicates the API functionality in the form of a postcondition and invariants.


DBC applied to Java

As described above, DBC and assertions are not part of the implementation. Rather, they are part of a class or interface specification. How can we isolate DBC and assertions from the implementation in Java? Here's an example of how we might apply assertions in Java: Suppose method m(x) asserts that x is never null. In Java, the code may form:

void m(Object x)
{
  assert(x != null);
}


In the above example, the assertion is part of the implementation; instead it should be part of the specification. In other words, the above example should form:

assert(x != null)
void m(Object x)
{
}


or

void m(Object x)
assert(x != null)
{
}


However, neither form will compile in Java. To effectively utilize DBC in Java, we must find an alternative mechanism, possibly Java's /** */ comment syntax. The special comments /** */ are most commonly used in front of class and method declarations. If you placed assertions inside these special comments, the Java compiler javac would ignore them.

1 | 2 | 3 | 4 |  Next >
Resources