三层架构(UBD)!!!

Posted 葡萄籽-June

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三层架构(UBD)!!!相关的知识,希望对你有一定的参考价值。

Get 三层架构

通过一些问题的思考,带着这些问题去了解一下三层架构叭!

1、什么是三层架构?
2、三层架构的作用是什么?如何体现?
3、三成架构针对的对象是什么?
4、三层架构如何应用?



三层架构

1、内容

1-1、表现层(User Interface layer)

主要是指与用户交互的界面。用于接收用户输入的数据和显示处理后用户需要的数据。

1-2、业务逻辑层(Business Logic Layer)

UI层和DAL层之间的桥梁。实现业务逻辑。业务逻辑具体包含:验证、计算、业务规则等等。(中间层)

1-3、数据访问层(Data access layer)

与数据库进行交互。主要实现对数据的增、删、改、查。将存储在数据库中的数据提交给业务层,同时将业务层处理的数据保存到数据库。

【补】实体层(Entity)

  • 1、实现面向对象思想中的"封装";

  • 2、贯穿于三层,连接三层,在三层之间传递数据;

  • 3、可以理解为:每个我们需要的表(由数据表对应而来的表)对应一个实体,即每个表中的字段对应实体中的属性。(视图是根据需求可变化的,视图中的字段能够存储到相应的实体类中。但是一个实体类需要抽象出可能这个实体所需要的所有属性的集合,因此,只要实体类能够包含应用需求中的字段存储就可以。)

  • 4、每一层(UI—>BLL—>DAL)之间的数据传递(单向)是靠变量或实体作为参数来传递的,这样就构造了三层之间的联系,完成了功能的实现。

【注】三层架构之间的联系简单描述图

(用户的需求反映给界面(UI),UI反映给BLL,BLL反映给DAL,DAL进行数据的操作,操作后再一一返回,直到将用户所需数据反馈给用户)

三层架构关系
实际上,除了上述三层和实体层外,往往在实际开发过程中还有工具类层。主要是一些工具的封装。

2、三层架构的作用

作为一个编程人员,高内聚,低耦合的思想是很重要的。当然,在三层架构中,这个也是密切相关的。

高内聚:一个模块中,各个元素彼此结合的紧密程度较高。
低耦合:一个完整的系统,模块与模块之间,尽可能地使其独立存在。即让每个模块,尽可能独立完成某个特定的子功能。模块与模块之间的接口,尽量的少而简单。如果两个模块之间的关系比较复杂的话,最好先考虑进一步划分,这样有利于修改和组合。

作用:解耦合。降低模块之间的耦合度。


3、三层架构的应用体现:

在不适用三层架构的设计思想时,用户界面、业务逻辑、操作数据等都是混在一起的。
首先,在原先的二层架构(基础)中代码可读性低,各个功能模块耦合性高,业务逻辑与用户界面与数据访问都是混着的。修改或者扩展代码的时候所付出的代价是很大的。
而三层架构针对于应用程序来说,在设计上将用户界面、业务逻辑、操作数据等划分开来,降低了各个代码块之间的耦合度,提升代码的阅读性、可扩展性等等。
最后,如何使用三层架构呢?将原来代码中业务逻辑、界面操作、数据库访问分层并且通过实体层进行联系并传递数据。并通过下面的源代码栗子进行三层架构的应用。

  • 项目架构
    项目架构
    项目详细架构
  • 数据访问层DAO接口

public interface StudentDao {
    /**
     * @Description //TODO  根据id查找学生
     * @Param  [id]
     * @return  com.wedu.entity.Student
     **/
    Student findOneById(int id);
    /**
     * @Description //TODO  验证登录
     * @Param  [name, password]
     * @return  com.wedu.entity.Student
     **/
    Student login(String name,String password);


}

  • 数据访问层实现DAO Impl
package com.wedu.dao.impl;

import com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper;
import com.wedu.dao.StudentDao;
import com.wedu.entity.Student;
import com.wedu.util.JDBCUtils;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;


public class StudentDaoImpl implements StudentDao {
    /**
     * 获取JDBCTemplate对象
     **/
    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
    /**
     * 数据库连接对象
     */
    Connection conn = null;
    /**
     * 数据库操作对象
     */
    PreparedStatement pstmt = null;
    /**
     * 结果集
     */
    ResultSet rs = null;

    /**
     * @return com.wedu.entity.Student
     * @Description //TODO  根据id查找学生
     * @Param [id]
     **/
    @Override
    public Student findOneById(int id) {
        //定义sql
        String sql = "select * from student where id = ?";
        try {
            return template.queryForObject(sql, new BeanPropertyRowMapper<Student>(Student.class), id);
        } catch (EmptyResultDataAccessException e) {
            System.out.println("无此id编号的学生信息");
            return null;
        }
    }

    /**
     * @return com.wedu.entity.Student
     * @Description //TODO  登录判断
     * @Param [name, password]
     **/
    @Override
    public Student login(String name, String password) {
        //定义sql
        try {
            String sql = "select * from student where name = ? and password = ?";
            // 返回 Student对象
            return template.queryForObject(sql, new BeanPropertyRowMapper<Student>(Student.class), name, password);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}

  • 业务逻辑层 Service 接口
package com.wedu.service;

import com.wedu.entity.Student;

public interface StudentService {

    /**
     * @return boolean
     * @Description //TODO 判断用户登录是否成功
     * @Param [name, password]
     **/
    boolean loginStu(String name, String password);

    /**
     * @return boolean
     * @Description //TODO  通过id查询用户信息
     * @Param [id]
     **/
    Student findStuById(int id);

}

  • 业务逻辑层 Service Impl
package com.wedu.service.impl;

import com.wedu.dao.StudentDao;
import com.wedu.dao.impl.StudentDaoImpl;
import com.wedu.entity.Student;
import com.wedu.service.StudentService;


public class StudentServiceImpl implements StudentService {

    //创建StudentDaoImpl对象
    private StudentDao studentDao = new StudentDaoImpl();

    @Override
    public boolean loginStu(String name,String password) {
        if(name == null || password == null){
            return false;
        }
        Student login = studentDao.login(name, password);
        if (login!=null){
            return true;
        }else {
            return false;
        }
    }

    @Override
    public Student findStuById(int id) {
        Student findOne=studentDao.findOneById(id);
//        在哪边进行为空判断?
        return findOne;
    }

}

  • 用户界面层
package com.wedu.view;

import com.alibaba.druid.sql.PagerUtils;
import com.wedu.entity.Student;
import com.wedu.service.StudentService;
import com.wedu.service.impl.StudentServiceImpl;
import org.junit.Test;

import java.util.InputMismatchException;
import java.util.Scanner;

/**
 * @ClassName : Login
 * @Description //TODO  用户界面UI
 **/
public class TestUnits {
    private StudentService studentService = new StudentServiceImpl();
    private Scanner sc = new Scanner(System.in);

    //登录测试
    @Test
    public void login() {
        //1.键盘录入,接收用户名和密码
        System.out.println("请输入用户名:");
        String name = sc.nextLine();
        System.out.println("请输入密码:");
        String password = sc.nextLine();
        //2.调用方法
        boolean flag = studentService.loginStu(name, password);
        //3.判断结果,输出不同语句
        if (flag) {
            //登录成功
            System.out.println("登录成功!");
        } else {
            System.out.println("用户名或密码错误!");
        }
    }

    /**
     * @return void
     * @Description //TODO   根据id查找学生
     * @Param []
     **/
    @Test
    public void findStuInfoById() {
        //1.键盘录入,接收用户名和密码
        System.out.println("请输入要查询的学生id:");

        int stuId;
        while (!sc.hasNextInt()) {
//                要拿一个next()接一下。不然会陷入死循环。
            String stu = sc.next();
            System.out.println("请用户输入整数哦!");
            System.out.println("请重新输入吖:");
        }
        stuId = sc.nextInt();
        //2.调用方法
        Student stuInfo = studentService.findStuById(stuId);
//        3、判断结果
        if (stuInfo == null) {
            System.out.println("查询失败!");
        } else {
            System.out.println("此Id用户的信息如下所示:");
            System.out.println(stuInfo.toString());
        }
    }

}

4、小结

三层架构的优势

  • 1,结构清晰、耦合度低
  • 2,可维护性高,可扩展性高
  • 3,利于开发任务同步进行, 容易适应需求变化

三层架构的劣势

  • 1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。
  • 2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。
  • 3、增加了代码量,增加了工作量。

以上是关于三层架构(UBD)!!!的主要内容,如果未能解决你的问题,请参考以下文章

图书馆管理系统_三层架构_MySQL

三层架构

三层架构 是设计模式吗

01三层架构简介

WPF MVVM 架构 Step By Step(简单的三层架构示例及粘合代码GLUE code)

三层架构与MVC