常見的三種開發模型:
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) {
// <user username="abc" password="123" email="[email protected]" 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="[email protected]" 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","[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點了,屌絲的我也該睡覺了,明天還得去上班的呢