常见的三种开发模型:
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;}@Overridepublic 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) {
//<user username="abc" password="123" email="617504296@qq.com" birthday="1970-01-01"/>
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+"']");
// <user username="zhongchengpeng" password="zhongchengpeng" email="617504296@qq.com" birthday="2016-10-27 22:43:51"/>
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<Node> 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","617504296@qq.com", new Date());
s.regist(user);
}
@Test(expected=com.zcp.exception.UserHasExistException.class)
public void testRegist1() throws UserHasExistException {
User user = new User("zhongchengpeng", "123456","617504296@qq.com", 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点了,屌丝的我也该睡觉了,明天还得去上班的呢