三层架构介绍

简介: 三层架构介绍

一、什么是三层架构?

1.1概述

三层架构(3-tier architecture) 就是将整个业务应用划分为:

  • 界面层(User Interface layer) UI
  • 业务逻辑层(Business Logic Layer) BLL
  • 数据访问层(Data Access layer) DAL

1.2表示层

  • 表示层,又称界面层,是与用户交互的界面。位于最外层/最上层,离用户最近,用于接收用户输入的数据和显示处理后用户需要的数据。
  • 【接受请求,封装数据,调用业务逻辑层,响应数据(servlet,jsp)】

1.3业务逻辑层

  • 业务逻辑层,又称服务层,是表示层和数据访问层之间的桥梁。位于中间层,用来处理业务逻辑,具体包含:验证、计算、业务规则等等。

1.4数据访问层

  • 数据访问层,是对数据库访问的层。位于最里层/最下层,主要实现对数据的增、删、改、查。将存储在数据库中的数据提交给业务层,同时将业务层处理的数据保存到数据库。

1.5层与层的关系

  • 表示层依赖于业务逻辑层
  • 业务逻辑层依赖于数据访问层

既然三层各司其责,那么怎么将三层联系起来?

这个时候实体层(Entity) 来了

  • Entity(实体层):它不属于三层中的任何一层,但是它是必不可少的一层
  • Entity在三层架构中的作用:
  • 1、实现面向对象思想中的"封装";
  • 2、贯穿于三层,在三层之间传递数据;(注:确切的说实体层贯穿于三层之间,来连接三层)
  • 3、每一层(UI—>BLL—>DAL)之间的数据传递(单向)是靠变量或实体作为参数来传递的,这样就构造了三层之间的联系,完成了功能的实现。

二、为什么需要三层架构?

三层架构的出现就是为了“高内聚,低耦合”

内聚:一个模块内各个元素的关联度。
耦合 :各个模块之间的关联度。
  • 高内聚 :尽可能一个类/模块只负责一个功能(一个模块内的元素关联度,越容易理解、修改和维护,出错就越少)。
  • 低耦合 :模块与模块之间的关联度要尽可能的低,避免牵一发而动全身
  • 从类角度来看:高内聚低耦合:减少类内部,对其他类的调用
  • 从功能块来看:高内聚低耦合:减少模块之间的交互复杂度

简单来说,就是解耦:减少模块之间的交互复杂度,自己做自己的事

三层: 发生在哪一层的变化,只需更改该层,不需要更改整个系统。层次清晰,分工明确,每层之间耦合度低——提高了效率,适应需求变化,可维护性高,可扩展性高

两层: 当任何一个地方发生变化时,都需要重新开发整个系统。“多层”放在一层,分工不明确耦合度高,难以适应需求变化,可维护性低、可扩展性低

三、层架构的应用

3.1原则

  • 上层依赖其下层,依赖关系不跨层
  • 表示层不能直接访问数据访问层
  • 上层调用下层的结果,取决于下层的实现
  • 下一层不能调用上一层
  • 下一层不依赖上一层
  • 上层的改变不会影响下一层
  • 下层的改变会影响上一层得到的结果
  • 在上一层中不能出现下一层的概念
  • 分工明确,各司其职

3.2例子:实现登录功能

表现层:jsp页面

<body>
    <div class="container" style="margin-top:140px;height: 100px;">
      <div class="row">
        <div class="col-md-6 bg-primary">
          <h2 class="text-white">欢迎登录</h2>
          <p class="text-white">商城后台管理系统</p>
        </div>
        <div class="col-6 bg-white py-5">
          <form action="login.do" method="post" onsubmit="return myLogin()">
            <div class="mb-3">
              <label for="exampleInputEmail1" class="form-label">邮箱账号</label>
              <input placeholder="请输入邮箱账号" ptype="email" class="form-control" id="exampleInputEmail1"
                aria-describedby="emailHelp" name="username">
            </div>
            <div class="mb-3">
              <label for="exampleInputPassword1" class="form-label">密码</label>
              <input placeholder="请输入密码" type="password" class="form-control" id="exampleInputPassword1" name="password">
            </div>
            <div class="mb-3">
              <label for="exampleInputPassword1" class="form-label">验证码</label>
              <div class="input-group mb-3 " style="width: 200px;">
                <input id="yz" placeholder="请输入验证码" type="text" class="form-control">
                <button id="login" type="button" class="btn btn-primary">
                  <span id="code" class="badge bg-danger">9888</span>
                </button>
              </div>
            </div>
            <button type="submit" class="btn btn-primary">登录</button>
          </form>
        </div>
      </div>
    </div>
  </body>

控制器Servlet

Servler通常作为控制器位于服务层和表示层之间,处理请求并相应地调用服务层方法执行业务逻辑

@WebServlet("/login.do")
public class LoginServlet extends HttpServlet {
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doPost(request, response);
  }
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // 设置编码
    request.setCharacterEncoding("utf-8");
    response.setCharacterEncoding("utf-8");
    response.setContentType("text/html;charset=utf-8");
    // 获取参数
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    // 处理请求
    PrintWriter out = response.getWriter();
    HttpSession session = request.getSession();
    //实例化业务逻辑层对象
    IUserService ius=new UserServiceImpl();
    User login = ius.login(username, password);
    System.out.println(login);
    if (login != null) {
      session.setAttribute("Login", login);
      out.println("<script>alert('登录成功');location.href='good.jsp'</script>");
    } else {
      out.println("<script>alert('账号或密码错误');location.href='login.jsp'</script>");
    }
  }
}

业务逻辑层

/**
 * 业务逻辑层
 * 定义接口类
 * @author 许潜行
 *
 */
public interface IUserService {
  /**
   * 用户登录方法
   * @param uname
   * @param upwd
   * @return
   */
  public User login(String uname,String upwd);
}
/**
 * 业务逻辑层
 * 实现接口类
 * @author 许潜行
 *
 */
public class UserServiceImpl implements IUserService {
  //实例化数据访问层对象
  private IUsersDao iud=new UsersDaoImpl();
  @Override
  public User login(String uname, String upwd) {
    return iud.login(uname, upwd);
  }
}

数据访问层

/**
 * 数据访问层
 * 定义接口
 * @author 许潜行
 *
 */
public interface IUsersDao {
  /**
   * 用户登录方法
   * @param uname
   * @param upwd
   * @return
   */
  public User login(String uname,String upwd);
}
/**
 * 数据访问层
 * 实现接口类
 * @author 许潜行
 *
 */
public class UsersDaoImpl extends BaseDao implements IUsersDao {
  Connection conn = null;
  PreparedStatement ps = null;
  ResultSet rs = null;
   public User login(String uname,String upwd) {
          User u=null;
          String sql="select * from tb_user where username=? and password=?";
          try {
            rs=this.executeQuery(sql, new Object[] {uname,upwd});
              if(rs.next()) {
                  u=new User(rs.getInt(1), rs.getString(2), rs.getString(3));
              }
          } catch (Exception e) {
              e.printStackTrace();
          } finally {
              DBHelper.myClose(conn, ps, rs);
          }
          return u;
      }
      public static void main(String[] args) {
      User login = new UsersDaoImpl().login("user123@qq.com", "a12345");
      System.out.println(login);
    }
}

实体类:

public class User {
  private Integer id;
  private String username;
  private String password;
  public User() {
    // TODO Auto-generated constructor stub
  }
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }
  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 User(Integer id, String username, String password) {
    super();
    this.id = id;
    this.username = username;
    this.password = password;
  }
  public User(String username, String password) {
    super();
    this.username = username;
    this.password = password;
  }
  @Override
  public String toString() {
    return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
  }
}

BaseDao

/**
   *增删改通用方法
   * @param sql
   * @param obj
   * @return
   */
  public int execute(String sql,Object...obj) {
    int n=0;
    try {
      //建立连接
      conn=DBHelper.getConn();
      //传入sql并执行
      ps=conn.prepareStatement(sql);
      //占位符赋值
      if (obj!=null) {
        for (int i = 0; i < obj.length; i++) {
          ps.setObject(i+1, obj[i]);
        }
      }
      //返回结果
      n=ps.executeUpdate();
    } catch (Exception e) {
      e.printStackTrace();
    }finally {
      //关闭资源
      DBHelper.myClose(conn, ps, rs);
    }
    return n;
  }
  /**
   * 查询通用方法
   * @param sql
   * @param obj
   * @return
   */
  public ResultSet executeQuery(String sql,Object...obj) {
    try {
      //建立连接
      conn=DBHelper.getConn();
      //传入sql并执行
      ps=conn.prepareStatement(sql);
      //占位符赋值
      if (null!=obj) {
        for (int i = 0; i < obj.length; i++) {
          ps.setObject(i+1, obj[i]);
        }
      }
      //返回结果
      rs=ps.executeQuery();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return rs;
  }


目录
相关文章
|
3月前
|
前端开发 Java fastjson
且谈软件架构(二) 模块化与MVC
且谈软件架构(二) 模块化与MVC
|
2月前
|
设计模式 前端开发 数据库连接
心得经验总结:浅谈三层架构
心得经验总结:浅谈三层架构
14 0
|
3月前
|
存储 设计模式 测试技术
了解三层架构:表示层、业务逻辑层、数据访问层
了解三层架构:表示层、业务逻辑层、数据访问层
1088 0
|
3月前
|
SQL 调度 数据库
三层架构,如何使用
三层架构,如何使用
|
数据库
三层架构小结
三层架构小结
48 0
|
存储 数据处理 数据库
C#三层架构
DAL(Data Access Layer),数据访问层。与数据库打交道。访问数据库,对数据表进行Select,Insert,Update,Delete操作,并且将处理后的数据保存到数据库
|
存储 数据库
三层架构总结
三层架构总结
109 0
|
数据库
三层架构——三层登录
三层架构——三层登录
97 0
|
SQL 存储 数据库
三层架构
三层架构
105 0