BS三层架构(Browser/Server three-tier architecture)是一种常见的软件架构模式,将一个应用程序分为三个主要的逻辑层:表示层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)。每个层有不同的职责和功能,通过清晰的分层结构提高了应用程序的可维护性、可扩展性和可测试性。
表示层(Presentation Layer):表示层是用户与系统交互的界面,负责接收用户的输入、展示数据和处理用户的操作。它通常包括用户界面、用户交互逻辑和展示数据的逻辑。表示层可以是Web页面、移动应用程序或桌面应用程序等。它与用户直接交互,并将用户的请求传递给业务逻辑层进行处理。
业务逻辑层(Business Logic Layer):业务逻辑层是应用程序的核心,负责处理业务逻辑和业务规则。它包含了应用程序的核心功能和处理逻辑。业务逻辑层接收来自表示层的请求,根据业务规则进行处理,并调用数据访问层来获取或更新数据。它独立于具体的表示层和数据访问层,可重用和测试。
数据访问层(Data Access Layer):数据访问层负责与数据存储系统(如数据库)进行交互,提供数据的读取和写入功能。它封装了与数据存储系统的交互细节,提供了对数据的访问接口供业务逻辑层使用。数据访问层可以使用SQL语句或ORM(对象关系映射)框架来操作数据库。
这种三层架构的好处是明确了各层之间的职责和关系,提高了代码的可维护性和可扩展性。表示层负责用户界面,业务逻辑层负责处理业务规则,数据访问层负责数据的读写。每个层都可以独立开发、测试和部署,降低了耦合度,方便团队合作和项目维护。
此外,BS三层架构还可以支持跨平台开发和前后端分离。前端可以使用不同的技术栈开发用户界面,后端可以使用不同的技术栈实现业务逻辑和数据访问。前后端通过API接口进行通信,实现了前后端的解耦和灵活性。
数据访问层负责与数据库进行交互,提供数据的读取和写入功能。在本示例中,我们使用了Java语言和JDBC技术来实现数据访问层。
public class UserDao {
// 数据库连接信息
private static final String URL = "jdbc:mysql://localhost:3306/test";
private static final String USERNAME = "root";
private static final String PASSWORD = "123456";
// 获取数据库连接
public Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USERNAME, PASSWORD);
}
// 查询所有用户
public List<User> findAll() {
List<User> userList = new ArrayList<>();
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = getConnection();
String sql = "SELECT * FROM user";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setAge(rs.getInt("age"));
userList.add(user);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (rs != null) rs.close();
if (ps != null) ps.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return userList;
}
// 根据ID查询用户
public User findById(int id) {
User user = null;
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = getConnection();
String sql = "SELECT * FROM user WHERE id=?";
ps = conn.prepareStatement(sql);
ps.setInt(1, id);
rs = ps.executeQuery();
if (rs.next()) {
user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setAge(rs.getInt("age"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (rs != null) rs.close();
if (ps != null) ps.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return user;
}
// 添加用户
public void add(User user) {
Connection conn = null;
PreparedStatement ps = null;
try {
conn = getConnection();
String sql = "INSERT INTO user(name, age) VALUES(?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1, user.getName());
ps.setInt(2, user.getAge());
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (ps != null) ps.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 更新用户
public void update(User user) {
Connection conn = null;
PreparedStatement ps = null;
try {
conn = getConnection();
String sql = "UPDATE user SET name=?, age=? WHERE id=?";
ps = conn.prepareStatement(sql);
ps.setString(1, user.getName());
ps.setInt(2, user.getAge());
ps.setInt(3, user.getId());
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (ps != null) ps.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 删除用户
public void delete(int id) {
Connection conn = null;
PreparedStatement ps = null;
try {
conn = getConnection();
String sql = "DELETE FROM user WHERE id=?";
ps = conn.prepareStatement(sql);
ps.setInt(1, id);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (ps != null) ps.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
业务逻辑层负责处理业务逻辑和业务规则。在本示例中,我们使用了Java语言和Servlet技术来实现业务逻辑层。
@WebServlet("/user")
public class UserServlet extends HttpServlet {
private UserDao userDao = new UserDao();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("action");
if ("list".equals(action)) {
list(request, response);
} else if ("add".equals(action)) {
add(request, response);
} else if ("edit".equals(action)) {
edit(request, response);
} else if ("update".equals(action)) {
update(request, response);
} else if ("delete".equals(action)) {
delete(request, response);
} else {
list(request, response);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
// 显示用户列表
private void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<User> userList = userDao.findAll();
request.setAttribute("userList", userList);
request.getRequestDispatcher("/user/list.jsp").forward(request, response);
}
// 显示添加用户页面
private void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/user/add.jsp").forward(request, response);
}
// 显示编辑用户页面
private void edit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int id = Integer.parseInt(request.getParameter("id"));
User user = userDao.findById(id);
request.setAttribute("user", user);
request.getRequestDispatcher("/user/edit.jsp").forward(request, response);
}
// 添加用户
private void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
User user = new User();
user.setName(name);
user.setAge(age);
userDao.add(user);
response.sendRedirect(request.getContextPath() + "/user?action=list");
}
// 更新用户
private void update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int id = Integer.parseInt(request.getParameter("id"));
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
User user = new User();
user.setId(id);
user.setName(name);
user.setAge(age);
userDao.update(user);
response.sendRedirect(request.getContextPath() + "/user?action=list");
}
// 删除用户
private void delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int id = Integer.parseInt(request.getParameter("id"));
userDao.delete(id);
response.sendRedirect(request.getContextPath() + "/user?action=list");
}
}
表示层负责用户与系统交互的界面,负责接收用户的输入、展示数据和处理用户的操作。在本示例中,我们使用了JSP技术来实现表示层。
<%-- user/list.jsp --%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
用户列表
用户列表
ID
姓名
年龄
操作
${user.id}
${user.name}
${user.age}
编辑
删除
添加用户
<%-- user/add.jsp --%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
添加用户
BS三层架构的优点:
分层清晰:BS三层架构将系统分为表示层、业务逻辑层和数据访问层,各层职责清晰,便于开发和维护。
可扩展性强:由于各层之间松耦合,所以可以很方便地对系统进行扩展和修改,而不会影响其他层的功能。
可重用性高:由于各层之间的分离,可以将每一层的功能进行封装和抽象,提高代码的可重用性。
并发性好:由于业务逻辑层和数据访问层可以部署在不同的服务器上,所以可以提高系统的并发性能。
BS三层架构的缺点:
开发复杂:相比于传统的MVC架构,BS三层架构需要开发更多的代码和配置,增加了开发的复杂度。
性能问题:由于业务逻辑层和数据访问层分布在不同的服务器上,所以在处理一些复杂的业务逻辑时可能会存在性能问题。
系统依赖:由于各层之间存在依赖关系,所以在修改某一层的代码时,可能会影响其他层的功能,增加了系统维护的难度。
学习成本高:BS三层架构需要掌握多种技术和工具,对开发人员的技术要求较高,学习成本相对较高。