三层架构介绍
Web应用项目开发的三层架构是一种常见的软件设计模式,它将应用程序分为三个逻辑层次:表示层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)。这种架构有助于提高代码的可维护性、可扩展性和可测试性。下面是对这三层的简要描述:
1. 表示层(Presentation Layer):
- 这一层负责与用户交互,展示数据(视图)并接收用户输入。
- 它通常由HTML、CSS和JavaScript等前端技术构成,用于构建用户界面。
- 在Web应用中,这一层可能包括Web页面、移动应用界面或其他客户端界面。
- 表示层不包含业务逻辑,它通过调用业务逻辑层来完成用户请求。
2. 业务逻辑层(Business Logic Layer):
- 这一层包含了应用程序的核心功能和业务规则。
- 它处理表示层的用户请求,执行必要的业务逻辑,如数据验证、事务处理等。
- 业务逻辑层通常由服务器端的应用程序代码构成,如使用Java、C#、Python等语言编写的代码。
- 这一层与数据访问层交互,以获取或存储数据。
3. 数据访问层(Data Access Layer):
- 这一层负责与数据库或其他持久化存储进行交互。
- 它提供了一组接口,用于执行CRUD(创建、读取、更新、删除)操作。
- 数据访问层通常使用数据库访问技术,如JDBC、ADO.NET、ORM(对象关系映射)框架等。
- 这一层将数据以一种抽象的方式提供给业务逻辑层,而不暴露数据库的具体实现细节。
三层架构的优点包括:
- 分离关注点:每一层都有其特定的职责,这有助于开发人员专注于各自的任务。
- 可维护性:由于层与层之间的耦合度低,修改一层不会影响其他层,这使得维护和升级变得更加容易。
- 可扩展性:可以根据需要独立扩展每一层,以应对不同的性能和功能需求。
- 可测试性:每一层可以独立进行单元测试,这有助于提高代码质量和发现潜在问题。
在实际开发中,三层架构可以根据项目的具体需求进行调整和优化。例如,可以使用微服务架构来进一步分解业务逻辑层,或者使用前端框架和库来增强表示层的功能。
我们来做一个案例来实现三层架构
第一步
我们做好提前工作:
1.我们先在一个新建的项目中创建一个用以存放建立逻辑处理层类的包service和存放数据访问层类的包dao,还有存放实体类的pojo包和控制类的controller包
2.引用解析XML文件的依赖
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
</dependency>
3.导入XML文件
第二步:
1.在pojo包编写实体类Emp和Result
package com.example.pojo;
/**
* 统一响应结果封装类
*/
public class Result {
private Integer code ;//1 成功 , 0 失败
private String msg; //提示信息
private Object data; //数据 data
public Result() {
}
public Result(Integer code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public static Result success(Object data){
return new Result(1, "success", data);
}
public static Result success(){
return new Result(1, "success", null);
}
public static Result error(String msg){
return new Result(0, msg, null);
}
@Override
public String toString() {
return "Result{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
package com.example.pojo;
/**
* 统一响应结果封装类
*/
public class Result {
private Integer code ;//1 成功 , 0 失败
private String msg; //提示信息
private Object data; //数据 data
public Result() {
}
public Result(Integer code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public static Result success(Object data){
return new Result(1, "success", data);
}
public static Result success(){
return new Result(1, "success", null);
}
public static Result error(String msg){
return new Result(0, msg, null);
}
@Override
public String toString() {
return "Result{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
2.建立数据访问层的借口和实现的类
package com.example.dao;
import com.example.pojo.Emp;
import java.util.List;
public interface EmpDao {
//获取员工数据
public List<Emp> listEmp();
}
package com.example.dao.impl;
import com.example.dao.EmpDao;
import com.example.pojo.Emp;
import com.example.dao.XmlParserUtils;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class EmpDaoA implements EmpDao {
@Override
public List<Emp> listEmp(){
String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
List<Emp> empList= XmlParserUtils.parse(file, Emp.class);
return empList;
}
}
3.建立逻辑处理接口和实现的类
package com.example.service;
import com.example.pojo.Emp;
import java.util.List;
public interface EmpService {
//获取员工列表
public List<Emp> listEmp();
}
package com.example.service.impl;
import com.example.dao.EmpDao;
import com.example.dao.impl.EmpDaoA;
import com.example.pojo.Emp;
import com.example.service.EmpService;
import java.util.List;
public class EmpServiceA implements EmpService {
//创建DAO对象
private EmpDao empDao =new EmpDaoA();
@Override
public List<Emp> listEmp(){
//调用DAO
List<Emp> empList = empDao.listEmp();
//处理数据
for (Emp emp : empList){
//处理性别
String gender = emp.getGender();
if("1".equals(gender)){
emp.setGender("男");
}else{
emp.setGender("女");
}
//处理job
String job = emp.getJob();
if("1".equals(job)){
emp.setJob("讲师");
}else if("2".equals(job)){
emp.setJob("班主任");
}else{
emp.setJob("就业指导");
}
}
return empList;
}
}
4.创建处理xml文件的类
package com.example.dao;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
public class XmlParserUtils {
public static <T> List<T> parse(String file , Class<T> targetClass) {
ArrayList<T> list = new ArrayList<T>(); //封装解析出来的数据
try {
//1.获取一个解析器对象
SAXReader saxReader = new SAXReader();
//2.利用解析器把xml文件加载到内存中,并返回一个文档对象
Document document = saxReader.read(new File(file));
//3.获取到根标签
Element rootElement = document.getRootElement();
//4.通过根标签来获取 user 标签
List<Element> elements = rootElement.elements("emp");
//5.遍历集合,得到每一个 user 标签
for (Element element : elements) {
//获取 name 属性
String name = element.element("name").getText();
//获取 age 属性
String age = element.element("age").getText();
//获取 image 属性
String image = element.element("image").getText();
//获取 gender 属性
String gender = element.element("gender").getText();
//获取 job 属性
String job = element.element("job").getText();
//组装数据
Constructor<T> constructor = targetClass.getDeclaredConstructor(String.class, Integer.class, String.class, String.class, String.class);
constructor.setAccessible(true);
T object = constructor.newInstance(name, Integer.parseInt(age), image, gender, job);
list.add(object);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
}
5.创建控制类EmpController
package com.example.controller;
import com.example.pojo.Emp;
import com.example.pojo.Result;
import com.example.service.EmpService;
import com.example.service.impl.EmpServiceA;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class EmpController {
private EmpService empService = new EmpServiceA();
@RequestMapping("/listEmp")
public Result list() {
List<Emp> empList = empService.listEmp();
return Result.success(empList);
}
}
- 实体类:
Emp
类用于表示员工信息,Result
类用于封装响应结果。 - 数据访问层:
EmpDao
接口定义了获取员工数据的方法,EmpDaoA
类实现了这个接口,使用XmlParserUtils
解析XML文件。 - 业务逻辑层:
EmpService
接口定义了获取员工列表的方法,EmpServiceA
类实现了这个接口,并处理了性别和职位的转换。 - XML解析工具类:
XmlParserUtils
类使用dom4j
库解析XML文件,并将数据映射到Java对象。 - 控制层:
EmpController
类定义了一个HTTP请求处理方法listEmp
,调用EmpService
获取员工列表并返回响应。
运行和测试
- 运行Spring Boot应用。
- 在浏览器或使用HTTP客户端访问
localhost:8080/listEmp
来测试员工列表的获取功能。
最后效果如图所示(作业演示,勿抄)