Avoid sending code redundancy in data format verification (assistant class)
Level: Intermediate
Brett mclaughlin (Brett@oreilly.com) writer and editor, O'Reilly and associates 2003 April
A well-designed verification process can improve data integrity, ensuring that your application runs smoothly and makes future data changes easier to handle. In this issue
In the best practice of EJB, Brett McLaughlin expanded the verification technique discussed in the article in the article and improved the initial concept.
In the previous column article, we first discussed the issue of data verification, which is one of the basic components of the enterprise application design. After quickly checking the two types of data verification of data format verification and business-specific verification, we discussed the most favorable layout of these two verification logic in the application code. At the end, we propose a good and effective solution for the data format and the business-specific verification, but we don't really solve the more complex situation you may encounter in this programming.
Especially for the data format verification code, we believe that the best way to handle it is to keep it close to the client, so that the processing overhead keeps the least. Because the sample application contains a business delegate class, we placed the verification logic. The problem arising from this layout is that it will introduce a lot of redundancy in your code.
Change management and data verification Change data format in an enterprise application is very common. Although the format of the ISBN and social security number is basically unchanged, the IP address and UPC code will not be unchanged. If the verification code is dispersed throughout the application, you must find each instance and change them one by one, this process is cumbersome, and it is easy to make mistakes. Also, if you leak a or two instances (this is a common mistake), then the data may be finally damaged by your own verification logic! If you have merged verification logic, you can benefit the entire application as long as you change a format.
In this skill article, we will once again discuss data format verification, introduce the data verification assistant class, which will allow us to close the verification process close to the client, and will not introduce any unnecessary code.
The merge verification logic uses the same data type as a parameter for multiple business methods across multiple business delegations, which is very common. For example, a book can be passed to the INVENTORY delegate search method and a Payment delegated procurement method. If the verification logic is associated with the two business delegates (like the above skill article), then there will be ISBN verification code in the end of these two methods.
The first step in improving the data format verification process is to move all verification logic to a helper class, and other methods can call the verification logic from this class as needed. This merge is not only reduced by code redundancy, and when we need, it is possible to maintain and change the data format of the application.
To achieve such a merger, we will use the Validator class, which simply provides a static method for the various data types we need to verify. Listing 1 shows the framework of such a class:
Note: You can call a simple method in Listing 1 from other classes such as business delegation, to perform verification logic on demand. Also note that these methods do not return to the Boolean value.
Listing 1. Validator framework
Package com.ibm.validation;
Import java.util.iterator;
Import java.util.list;
Public class validator {
Public Static void validateisbn (String ISBN)
Throws invaliddataException {
// check the data type, and throw an error if
// NEEDED
}
Public Static Void ValidateIpAddress (String ipaddress)
Throws invaliddataException {
// Check Data Type
}
Public Static Void ValidateUpc (String Upc)
Throws invaliddataException {
// Check Data Type
}
Public Static Void ValidateUpc (Float Upc)
Throws invaliddataException {
ValidateUPC (New String (Upc));
}
Public Static Void ValidateList (List List, Class Class)
Throws invaliddataException {
Iterator i = list.iterator (); i.hasnext ();) {
Object obj = i.next ();
IF! (Obj InstanceOf Class) {
Throw new INVALIDDATAEXCEPTION ("this list only"
"Accepts Objects of Type"
Class.getname ());
}
}
}
}
Listing 2 shows a little messy code, which is the result of the use of Boolean return values.
Listing 2. Use Boolean back to Validator
Public Boolean Checkout (list books) throws ApplicationException {
IF (Validator.ValidateList (Books, Book.class) {
Try {
Return Library.checkout (Books);
} catch (remoteException E) {
Throw New ApplicationException (E);
}
}
}
Public Book Lookup (String ISBN) throws ApplicationException {
IF (Validator.Validateisbn (ISBN)) {
Try {
Return Library.lookup (ISBN);
} catch (remoteException E) {
Throw New ApplicationException (E);
}
}
}
In a more complex method, the above nested even makes even more messy. By allowing the abnormality, we have avoided the additional complexity generated by this mess, and the code remains more "clean". Also note that invalidDataException inherits ApplicationException. This allows the characterization of all delegated methods to remain unchanged, and thus any verification exception is allowed to throw any verification through the same mechanism. We don't have to add other THROWS clauses to the method characteristic, nor does it need to add other TRY / CATCH blocks to the method entity. In short, it keeps the code clean and simple, and will not be full of parentheses, application exceptions, verification exceptions, and IF / THEN and TRY / CATCH blocks.
Using Validator For the specific data type we need to verify, it is easy to use the validator in place and set it, it is easy to use in our application, especially in our business delegation method. Listing 3 focuses on the delegation in the article in the article, so it can use the new Validator class.
Listing 3. Data format verification in business delegation
Package com.ibm.library;
Import java.rmi.remoteexception; import java.util.ITerator;
Import java.util.list;
Import javax.ejb.createException;
Import javax.naming.namingexception;
Import com.ibm.validation.validator;
Import com.ibm.validation.invaliddataException;
Public class librarydelegate imports ilibrary {
Private iLibrary Library;
Public librarydelegate () {
INIT ();
}
Public void init () {
// Look Up and Obtain Our session bean
Try {
LibraryHome LibraryHome =
(Libraryhome) ejbhomefactory.getInstance (). Lookup
"Java: comp / env / ejb / libraryhome", libraryhome.class;
Library = libraryhome.create ();
} catch (namingexception e) {
Throw new runtimeException (e);
} catch (createException e) {
Throw new runtimeException (e);
} catch (remoteException E) {
Throw new runtimeException (e);
}
}
// no validation request for accessor (getter) Methods
Public Boolean Checkout (book book) throws ApplicationException {
// no validation request here; The Object Type
// Takes Care of IT
Try {
Return Library.checkout (BOOK);
} catch (remoteException E) {
Throw New ApplicationException (E);
}
}
Public Boolean Checkout (list books) throws ApplicationException {
// Validate List
Validator.Validatelist (Books, Book.class);
Try {
Return Library.checkout (Books);
} catch (remoteException E) {
Throw New ApplicationException (E);
}
}
Public Book Lookup (String ISBN) throws ApplicationException {
// Validate ISBN
Validator.Validateisbn (ISBN);
Try {
Return Library.lookup (ISBN);
} catch (remoteException E) {
Throw New ApplicationException (E);
}
}
// and so on ...
Public void destroy () {
// in this case, do nothing
}
}
Use independent Validator to make the code more modular and easier to maintain. In addition, we have moved all validation logic to one place to avoid redundancy in your code. The result is a better, more unlibrated application.
In this series of next technological articles, we will study on another aspect of verification: abnormal treatment. At that time.