Diagnosing and correcting recurring error types in Java programs

Source: Internet
Author: User
Tags abstract class operator copy
Program | Error Welcome to the diagnostic Java code, a new weekly update column, focusing on Java solutions related to your day-to-day programming work. This is the first article that introduces the concept of error patterns, a very useful concept that will improve your ability to detect and correct errors in your code. You'll learn about one of the most common error patterns that will lay the groundwork for you to start identifying and avoiding more advanced error patterns.
Error patterns and why they are useful
Just as good programming skills involve many design patterns (you can combine and apply these patterns in different program contexts), good debugging skills also involve a certain understanding of the error pattern. The error pattern is the recurring interrelationship between the errors that have been emitted and the potential errors in the program. This concept is not new to programming. Doctors rely on similar types of relationships in diagnosing disease. They learn this by working together with older doctors during the internship. Their education is focused on doing this kind of diagnosis. In contrast, the education of our software engineers is focused on process design and algorithmic analysis. While these skills are important, there is little concern about the education of the process of debugging. Instead, we have to "pick up" the skills ourselves. With the advent of extreme programming and its focus on unit testing, this practice has begun to change. But frequent unit tests only partially solve the problem. Once errors are found, they must be diagnosed and corrected. Fortunately, many of these errors follow one of several error patterns that we can identify. Once you have identified these error patterns, you can diagnose the cause of the error and correct it more quickly.

The error pattern is related to the reverse mode, which is the pattern of a common software design that has been proven to fail again and again. While the reverse mode is design mode, the error pattern is the pattern of incorrect program behavior associated with programming errors. This is not related to design at all, but to programming and debugging processes.

Learn by example
To illustrate the idea behind the error pattern, let's consider a basic error pattern that often happens to novice programmers (and, more often, more advanced developers). In a later article, we'll talk about more advanced error patterns. For each pattern, I will discuss programming principles that will help to minimize the occurrence of errors in the pattern (not implying that all errors are the result of not following programming principles; we all make mistakes no matter how many principles we follow).

For the sake of classification, I will generalize the error pattern description by using the following form, which I use in medical terms:

Pattern name
Symptoms
Cause
Treatment methods and preventive measures
Rogue Tile Mode
Perhaps it is the most common error pattern for novice programmers, because copying and pasting a piece of code into other parts of the program. Sometimes, a small portion of the replication changes because of a slightly different functional requirement. Inevitably, errors are fixed in one copy and not fixed in another copy, which can cause headaches when the symptoms relapse. Although most programmers soon became familiar with this error pattern, few of them took the appropriate steps to minimize the occurrence of such errors. It's easy to slack off thinking and simply copy the code that you think is ready to run. But productivity is lost because of code revisions, because an indiscriminate copy-and-paste operation quickly reduces any productivity that the replication code brings.

I call this the Rogue Tile model because each copy of a piece of code can be viewed as a "Tile" that is distributed in a program. The copy becomes "rogue tile" because of the differences in the code in the different replicas.

Symptoms
The most common symptom of this pattern of errors is that the program continues to behave incorrectly after you think you have fixed the problem.

Cause
To understand why this happens, let's look at the following two-Dollar Tree class hierarchy:

Public abstract class Tree {

}

public class Leaf extends tree {

public Object value;
...
}

public class Branch extends tree {

public Object value;
Public tree left;
The public is right;
...
}






The first thing to note for these classes is that both concrete classes contain the Value field of type Object. If you decide to let the tree contain, say, Interger later, you may forget to update one of the field declarations. If the other parts of the program require these fields to be Interger, the program will most likely not compile. You may recall that you changed the type of the value field of one of the classes, but ignored the fact that you did not make the corresponding changes in the other classes.

Some preventive measures
Of course, the error shown in this example is that the novice programmer can quickly learn to avoid by breaking out common code. In this case, the field declaration should be moved to the tree class. Its two subclasses inherit this field, and any changes to the field declaration only need to appear in one place.

Looking at this example, we might also write a method to add and multiply all nodes in a tree. For simplicity's sake, I'll write these methods in a recursive way.

In class Tree:

public abstract int Add ();
public abstract int multiply ();

In class Branch:

public int Add () {
return This.value.intValue () + left.add () + Right.add ();
}

public int Multiply () {
return This.value.intValue () * left.multiply () + right.multiply ();
}

In class Leaf:

public int Add () {return this.value.intValue ();}
public int Multiply () {return this.value.intValue ();}






Notice the error I introduced for the Branch class in the Multiply method: I didn't use the third to multiply, but I added it. The error occurred because I created the multiply method by copying the code in the Add method and making minor (but not complete) changes. This error is very subtle, because invoking the multiply method never emits an error signal. In fact, in many cases, it will return a seemingly perfectly reasonable result.

As before, we can control this error to the minimum by splitting out common code. In this case, we can write a separate method that accumulates an operator (passed as a parameter) on the tree. We can use a design pattern called public mode (not the wrong pattern!). Encapsulates this operator in the object.

Public abstract class Operator {
public abstract int Apply (int l, int r);
}

public class Adder extends Operator {
public int apply (int l, int r) {
return L + R;
}
}

public class Multiplier extends Operator {
public int apply (int l, int r) {
return L * r;
}
}






We can then change this method in our tree class hierarchy as shown in the following code:

In class Tree:

public abstract int accumulate (Operator o);

public int Add () {
Return This.accumulate (New Adder ());
}

public int Multiply () {
Return This.accumulate (New multiplier ());
}

In class Leaf:

public int accumulate (Operator o) {
return Value.intvalue ();
}


In class Branch:

public int accumulate (Operator o) {
Return o.apply (This.value.intValue (),
O.apply (Left.accumulate (o),
Right.accumulate (o)));
}






By factoring out common code, we eliminate the possibility of a copy-paste error in the body of the add and multiply methods. Also, note that we no longer need to write separate add and multiply methods for each subclass of tree.

It's a good habit to break out of public code, but it doesn't apply to all situations. For example, the simplicity of the Java type system often forces us to choose between precise type checking and maintaining a single point of control over each of the different functional elements of the program (see Resources for reading the article I wrote about NextGen). Because of this, the Rogue Tile pattern is one of the types of errors that all developers must keep trying to control to the minimum.

What is the next piece of content?
In short, this is our first error pattern. You may want to cut it down and pin it on your bulletin board as a reminder.

Mode: Rogue Tile
Symptom: The code seems to show that the error that was corrected before is still present.
Cause: Copy-The At least one copy of the pasted code fragment also contains errors that have been fixed in other replicas.
Treatment and prevention: if possible, break out common code, otherwise update it. Avoid copying and pasting code.
In my next article, I'll explore some of the other common bug patterns that have occurred in Java code. We will look specifically at the error patterns that appear as null pointer exceptions and discuss how to minimize their occurrences.

Resources

Access mode home page, which is an excellent home page that describes design patterns and how to use them.
The Anti-mode home page provides information and links to books about the subject.
If you haven't done so, consult extreme programming, a powerful new way to quickly develop concise, robust software.
Then download JUnit and start unit tests immediately.
Eric Allen's article on NextGen (an extension of a runtime generic type in Java) illustrates how a more powerful type system can help mitigate some of the pressures that exist between breaking down common code and using the type system to catch errors during compilation, two goals.


About the author
Eric Allen received a bachelor's degree in Computer Science and mathematics at Cornell University. He is currently the leader of Cycorp's Java software developer and a work-study master of the programming language group at Rice University. His research involved formal semantic models and extensions of the Java language, both at the source code and at the byte-code level. Currently, he is implementing a compiler from source code to bytecode for the NextGen programming language, which is an extension of the Java language's generic run-time type.



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.