常见的三种开发模型:

1、

Model1:JSP+JavaBean

2、

Model2:MVC

3、Model2+三层架构

今天就重点学习一下Model2+三层架构的编程思想。三层架构主要包括:表现层、业务逻辑层、数据访问层。我们在用三层框架编写程序的时候,一定要按照需求来写我们的程序。这样既有利于程序的快速搭建整体框架,同时又使我们自己的思路相对清晰,从而提高效率。

下面来看一个简单的实例:

简单的注册和登录信息

要求如下:

XXX网站

注册:

用户名:

密码:

重复密码:

邮箱:

生日:

有一个简单的注册页面,外加一个登录页面,登录使用注册信息中的用户名和密码。

那么,看到这个简单的需求后如何展开我们的编程呢?我想对于一个新手来说。感觉有点丈二和尚摸不着头脑,如果你跟我一样,那么请看下面,我们一起来学习学习。


编写步骤:

一、需求分析:

注册页面包括写什么信息,我们如何设计JavaBean呢?我们如何定义接口呢?我们如何实现接口呢?我们如何保证我们的接口可行呢?

(1)、根据需求分析,我们设计JavaBean(包括 username password email birthday)User。

所以我们定义的类如下:

    

package com.zcp.domain;
import java.util.Date;
public class User {
private String username;//唯一
private String password;
private String email;
private Date birthday;
public User(){}
public User(String username, String password, String email, Date birthday) {
super();
this.username = username;
this.password = password;
this.email = email;
this.birthday = birthday;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password
+ ", email=" + email + ", birthday=" + birthday + "]";
}
}

(2)、定义业务接口。我们主要实现注册和登录。所以业务接口就定义如下:

package com.zcp.service;
import com.zcp.domain.User;
import com.zcp.exception.UserHasExistException;
public interface BusinessService {
//抛出有补救措施的异常
/**
 * 注册新用户
 * @param 封装了用户信息的user对象
 * @throws UserHasExistException 如果用户名已经存在,抛出此异常
 * */
void regist(User user) throws UserHasExistException;
/**
 * 用户登录
 * @param username 用户名
 * @param password 密码
 * @return 用户名或者密码错误,返回null
 * */
User login(String username,String password);
}

(3)、实现业务接口:(注意:这里没有真实的数据库,只有用xml组成简单的数据库。理解一下,我也是新手额)

package com.zcp.service.impl;


import com.zcp.dao.UserDao;

import com.zcp.dao.impl.UserDaoXmlImpl;

import com.zcp.domain.User;

import com.zcp.exception.UserHasExistException;

import com.zcp.service.BusinessService;


public class BusinessServiceImpl implements BusinessService {

private UserDao dao = new UserDaoXmlImpl();

public void regist(User user) throws UserHasExistException {


//根据用户名查询用户名是否存在

User dbUser = dao.findByUsername(user.getUsername());

if(dbUser != null){

throw new UserHasExistException("用户名:"+ user.getUsername()+"已经存在了");

}

dao.save(user);

}


public User login(String username, String password) {

return dao.findUser(username,password);

}


}

(4)、在实现业务接口的时候肯定是需要访问数据库的,所以自然就想到需要dao层。所以我需要定义在实现业务接口中的dao的接口并实现;

dao接口的定义:

package com.zcp.dao;


import com.zcp.domain.User;


public interface UserDao {


/**

* 根据用户名查询用户是否存在

* @param username

* @return 不存在返回null

* */

User findByUsername(String username);


/**

* 保存用户信息

* @param user

* */

void save(User user);


/**

* 根据用户名和密码查询

* @param username

* @param password

* @return 查询到用户返回User,用户名或者密码错误返回null

* */

User findUser(String username, String password);


}

dao接口中的实现:(注意这里是用xml的形式保存的,如果对xml解析不熟悉。请查阅相关的xml知识)

package com.zcp.dao.impl;


import java.text.DateFormat;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;


import org.dom4j.Document;

import org.dom4j.Element;

import org.dom4j.Node;


import com.zcp.dao.UserDao;

import com.zcp.domain.User;

import com.zcp.util.Dom4jUtil;


public class UserDaoXmlImpl implements UserDao {


public User findByUsername(String username) {

try {

Document doc = Dom4jUtil.getDocument();

Node node = doc.selectSingleNode("//user[@username='"+username+"']");

if(node == null){

return null;

}

String xmlBirthday = node.valueOf("@birthday");

DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

Date birthday = df.parse(xmlBirthday);

User user = new User(node.valueOf("@username"), node.valueOf("@password"), node.valueOf("@email"), birthday);

return user;

} catch (Exception e) {

throw new RuntimeException(e);

}

}


public void save(User user) {

//


try {

Document doc = Dom4jUtil.getDocument();

Element eroot =doc.getRootElement();

eroot.addElement("user").addAttribute("username", user.getUsername())

.addAttribute("password", user.getPassword())

.addAttribute("email", user.getEmail())

.addAttribute("birthday", user.getBirthday().toLocaleString());

Dom4jUtil.write2xml(doc);

} catch (Exception e) {

throw new RuntimeException(e);

}

}


public User findUser(String username, String password) {

/*try {

Document doc = Dom4jUtil.getDocument();

//Node node = doc.selectSingleNode("//user[@username='"+username+"']");

//Node node = doc.selectSingleNode("//user[@username='"+username+"' and @password='"+password+"']");

//

Node node = doc.selectSingleNode("//user[@username='"+username+"' and @password='"+password+"']");

if(node == null){

return null;

}

String xmlbirthday = node.valueOf("@birthday");

DateFormat df = new SimpleDateFormat();

Date birthday = df.parse(xmlbirthday);

User user = new User(node.valueOf("@username"), node.valueOf("@password"), node.valueOf("@email"), birthday);

return user;

} catch (Exception e) {

throw new RuntimeException(e);

}*/

try {

Document doc = Dom4jUtil.getDocument();

// List userNodes = doc.selectNodes("//user");

Node node = doc.selectSingleNode("//user[@username='"+username+"' and @password='"+password+"']");

if(node==null)

return null;

String xmlBirthday = node.valueOf("@birthday");

DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

Date birthday = df.parse(xmlBirthday);

User user = new User(node.valueOf("@username"), node.valueOf("@password"), node.valueOf("@email"), birthday);

return user;

} catch (Exception e) {

throw new RuntimeException(e);

}

}


}

(5)在实现dao的时候,由于是采用的xml的形式。所以自然想到可以写一个简单的工具类,能够解析xml并且可以保存;所以顺理成章的就写了一个简单的工具类;

package com.zcp.util;


import java.io.FileOutputStream;

import java.net.URL;


import org.dom4j.Document;

import org.dom4j.DocumentException;

import org.dom4j.io.OutputFormat;

import org.dom4j.io.SAXReader;

import org.dom4j.io.XMLWriter;


public class Dom4jUtil {


private static String xmlRealpath;

static{

ClassLoader cl = Dom4jUtil.class.getClassLoader();

URL url = cl.getResource("users.xml");

xmlRealpath = url.getPath();

}

public static Document getDocument() throws Exception{

SAXReader reader = new SAXReader();

return reader.read(xmlRealpath);

}

public static void write2xml(Document document)throws Exception{

XMLWriter writer = new XMLWriter(new FileOutputStream(xmlRealpath), OutputFormat.createPrettyPrint());

writer.write(document);

writer.close();

}

}

(6)这样我们的业务方法基本完成了。那接下来我们是不是应该对我们的业务方法进行单元测试呢,所以理所当然的就想到了junit的单元测试:

package com.zcp.test;


import static org.junit.Assert.*;


import java.util.Date;


import javax.jws.soap.SOAPBinding.Use;


import org.junit.Test;


import com.zcp.domain.User;

import com.zcp.exception.UserHasExistException;

import com.zcp.service.BusinessService;

import com.zcp.service.impl.BusinessServiceImpl;


public class BusinessServiceImplTest {


private BusinessService s = new BusinessServiceImpl();

@Test

public void testRegist() throws UserHasExistException {

User user = new User("zhongchengpeng", "123456","[email protected]", new Date());

s.regist(user);

}

@Test(expected=com.zcp.exception.UserHasExistException.class)

public void testRegist1() throws UserHasExistException {

User user = new User("zhongchengpeng", "123456","[email protected]", new Date());

s.regist(user);

}


@Test

public void testLogin() {

User user = s.login("zhongchengpeng", "123456");

assertNotNull(user);

user = s.login("zhongchengpeng", "123");

assertNull(user);

user = s.login("zcp", "123456");

assertNull(user);

}


}

(7)、到这里我们的业务方法就已经写完了。我们就可以很好的使用我们的业务接口啦。至于后面的页面就明晚继续了,好像快12点了,屌丝的我也该睡觉了,明天还得去上班的呢