用户注册系统的Refactoring(重整)过程(2)
板桥里人 http://www.jdon.com 2002/06/15
很显然,我们要为现在的用户系统提供一个接口:这个接口可以在适当时候切换到客户自己的用户注册数据库,只做两件工作:修改一个变量;添加一套对客户的用户注册数据库操作程序。
为这个目标,我们开始重整(重构),怎么重整,当然使用设计模式,那么使用什么设计模式?
用户密码验证可以看成一个对象,从需求目标来看,面对整个系统的其他子系统,用户密码验证这个对象是不变的,变化的是产生用户密码验证这个对象的方法,或者说,制造这个对象的不同方法:有两个:一个来自本地数据库的制造过程;一个可能来自客户自己的数据库的制造过程。
工厂方法无疑是最适合的模式,关于设计模式,见网站的另外系列:"设计模式"
工厂模式关键两个要素是;"产品"和"工厂";
这个产品一般是一个接口类;这里我们为"用户密码验证"设计一个接口:
public interface AuthorizationIF{
public static final String authtypeone="local";
public static final String authclassone="com.XXX.AuthOneDb";
//第二套密码检查方案 可接上 特定系统 如 通行证系统等
public static final String authtypetwo="remote";
public static final String authclasstwo="??";
public static final String entimeformat = "yyyy.MM.dd
kk:mm:ss";
/**
* 新用户注册时,使用该方法加入新的密码
*
*/
public void insertPassword(int userid,String email,String
password)
throwsException;
/**
* 用户修改密码
* @param userid newpassword
*/
public void updatePassword(int userid,String newpassword)
throws Exception;
/**
* 检查用户输入的Email和Password是否正确
*
*/
public boolean checkEmailDB(String email,String password)
throws Exception;
.....
/**
* 忘记密码时,使用本方法获取密码
* @param email
* @return password
*/
public String getPassword(String email) throws Exception;
}
|
在这个AuthorizationIF中,我们相当于完成了所有有关密码方面的工作,这也是符合单一对象完成单一功能的目标。
再看看“工厂”,在工厂中,我们要提供不同方法来这个AuthorizationIF:
public class AuthorizationFactory {
private static Object initLock = new Object();
//目前我们使用 authclassone,我们自己的数据库;
//如果将来使用客户注册数据库,我们只要修改这里就可以。
private static String className = AuthorizationIF.authclassone;
private static AuthorizationIF factory = null;
public static AuthorizationIF getInstance() throws
Exception{
if (factory == null) {
synchronized(initLock) {
if (factory == null) {
try {
Class c = Class.forName(className);
factory= (AuthorizationIF)c.newInstance();
}catch (Exception e) {
throw new Exception("Exception loading
AuthorizationIF
class: " +className + e);
}
}
}
}
return factory;
}
}
|
在上面方法中我们是使用"com.XXX.AuthOneDb"这个程序来真正进行密码验证,但是这个程序实际上已经隐藏在AuthorizationIF
和 AuthorizationFactory后面。
而整个系统的其他子系统是与AuthorizationIF 和 AuthorizationFactory打交道的:
AuthorizationIF auth=AuthorizationFactory.getInstance();
这样,就将具体方法和其他子系统隔离开来,万一这个具体方法变化,比如使用客户自己的用户注册数据库,只要修改AuthorizationFactory一个参数就可以。
至此,refactoring完成,在这个过程中,我们要不修改系统的外观,比如JsP程序,我们基本没有变化,变化的是以前的password.java这个程序。
在refactoring之前,password.java是个纯粹的访问password数据库的数据操作bean,现在我们已经把password的操作封装在AuthOneDb中了,那么需要修改password.java,以便与之联系的前台Jsp没有变化。
password.java
public class Password {
protected int userid = 0;
protected String newpassword = "";
protected String newpassword2 = "";
protected String email = "";
public void setUserid(int userid) { this.userid =
userid; }
public void setNewpassword(String newpassword) {
this.newpassword = newpassword; }
public void setNewpassword2(String newpassword2) {
this.newpassword2 = newpassword2; }
//getmypassword
public void setEmail(String email) { this.email =
email; }
/** 改变密码
* @param userid
* @param newpassword
*
*/
public void update() throws Exception
{
if (newpassword == null || newpassword.equals("")
|| newpassword2 == null || newpassword2.equals("")
|| !newpassword.equals(newpassword2))
{
throw new Exception("something wrong with
new Password maybe not
same!");
}
AuthorizationIF auth=AuthorizationFactory.getInstance();
auth.updatePassword(userid,newpassword);
}
/** 获得忘记的密码
* @param email
* @return String password
*/
public String getMypassword(String which) throws Exception{
AuthorizationIF auth=AuthorizationFactory.getInstance();
return auth.getPassword(email);
}
}
|
对比refactoring之前,password.java方法名称没有改变,只是改变了方法体。所以使用该javabean的Jsp程序也就不用变化,注册系统的外观就没有改变。
下页
案例下载
JavaBean和JSP/JDBC操作数据库
|