常见的三种开发模型:

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点了,屌丝的我也该睡觉了,明天还得去上班的呢