分享
 
 
 

EJB 最佳实践:验证助手类

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

在数据格式验证中避免出现代码冗余方面提供一点帮助(助手类)

级别:中级

Brett McLaughlinbrett@oreilly.com

作家兼编辑,O'Reilly and Associates

2003 年 4 月

设计良好的验证过程可以提高数据完整性、确保您的应用程序顺利运行并使未来的数据更改更易于处理。在这一期的 EJB 最佳实践中,Brett McLaughlin 扩充了上一篇技巧文章中讨论的验证技术,并改进了最初的概念。

上一篇专栏文章中,我们首先讨论了数据验证方面的问题,这是企业应用程序设计的基本组件之一。在快速检查了数据格式验证和特定于业务的验证这两种类型的数据验证之后,我们讨论了这两种验证逻辑在应用程序代码中最有利的布局。在结束时我们针对数据格式和特定于业务的验证,提出了很好且有效的解决方案,但我们没有真正解决您在这一编程领域可能会遇到的更复杂情况。

特别是对于数据格式验证代码,我们认为处理它的最佳方法是使它接近客户机,这样可以使处理开销保持最少。因为示例应用程序包含了一个业务委派类,所以我们在其中放置了验证逻辑。这个布局产生的问题是它会在您的代码中引入许多冗余。

变更管理和数据验证

在企业应用程序中更改数据格式是十分常见的情况。尽管 ISBN 和社会保障号的格式基本不变,但 IP 地址和 UPC 代码却不会一成不变。如果验证代码分散在整个应用程序中,那么您必须找到每个实例,并逐一更改它们,这个过程很繁琐,而且易于出错。另外,如果您漏改了一个或两个实例(这是人们常犯的错误),那么数据可能就最终被您自己的验证逻辑破坏!

如果您已经合并了验证逻辑,那么只要更改一处的格式,就可以使整个应用程序受益。

在本篇技巧文章中,我们将再次讨论数据格式验证,介绍数据验证助手类,它将让我们使验证过程接近客户机,同时不会引入任何不必要的代码。

合并验证逻辑

对跨多个业务委派中的多个业务方法使用相同的数据类型作为参数,这是十分常见的。例如,可以将一本书的 ISBN 传递给 Inventory 委派的搜索方法和 Payment 委派的采购方法。如果将验证逻辑与这两个业务委派(象上一篇技巧文章中的那样)联系在一起,那么最终这两个方法中都会有 ISBN 验证代码。

改进数据格式验证过程的第一步是将所有的验证逻辑都移至一个助手类中,其它方法可以按需从这个类上调用验证逻辑。这种合并不仅减少了代码冗余,而且当我们需要时,能够维护和更改应用程序的数据格式。

要实现这样的合并,我们将使用 Validator 类,它为我们需要验证的各种数据类型简单地提供了静态方法。清单 1 显示了这样一个类的框架:

注:可以从诸如业务委派等其它类上调用清单 1 中的简单方法,以按需执行验证逻辑。还要注意这些方法不返回布尔值。

清单 1. Validator 框架

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 {

for (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());

}

}

}

}

清单 2 显示了一种有点杂乱的代码,这是使用布尔返回值产生的结果。

清单 2. 在 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);

}

}

}

在更复杂的方法中,上述嵌套甚至会变得更为杂乱。通过允许抛出异常,我们已避免了这种杂乱所产生的额外复杂性,并使代码保持更“整洁”。另外,请注意 InvalidDataException 继承了 ApplicationException。这允许所有委派方法的特征符保持不变,因而也允许通过相同机制来抛出任何验证异常。我们不必向方法特征符添加其它 throws 子句,也不必向方法主体添加其它 try/catch 块。简而言之,它使代码保持整洁和简单,而不会到处充斥括号、应用程序异常、验证异常以及 if/then 和 try/catch 块。

使用 Validator

针对我们需要验证的特定数据类型,在将 Validator 置于适当位置并对它作设置之后,在应用程序中使用它就很容易,在我们的业务委派方法中尤其如此。清单 3 中重写了上一篇技巧文章中的委派,以使它能使用新的 Validator 类。

清单 3. 业务委派中的数据格式验证

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 implements 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 required for accessor (getter) methods

public boolean checkout(Book book) throws ApplicationException {

// No validation required 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

}

}

使用独立的 Validator 使代码更模块化和更易维护。另外,我们已将所有的验证逻辑移至一处,从而避免代码中出现冗余。其结果是一个更佳、更不易出错的应用程序。

在本系列的下一篇技巧文章中,我们将研究验证的另一方面:异常处理。那时网上见。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有