如果我们尝试把编程的复杂架构缩小到最容易理解的程度,那么编程开发其实只做3件事:”
定义属性
、创建方法
、调用展示
“。但因为同类所需的内容较多,如一系列的属性,一堆的方法实现,一组的接口封装,那么就需要合理的把这些内容分配到不同的层次中去实现,因此有了分层架构的设计。
分层架构是将软件模块按照水平切分的方式分成多个层,一个系统由多层组成,每层由多个模块组成。同时,每层有自己独立的职责,多个层次协同提供完整的功能。比如,我们经常提到的MVC架构,就是一种非常典型非常基础的分层方式。
分层设计的本质其实就是将复杂问题简单化,基于单一职责原则让每层代码各司其职,基于“高内聚,低耦合”的设计思想实现相关层对象之间的交互。从而,提升代码的可维护性和可扩展性。
系统架构分层之后,往往需要达到以下目标:
- 高内聚:分层设计可以简化系统设计,让不同层专注做某一模块的事;
- 低耦合:层与层之间通过接口或API来交互,依赖方不用知道被依赖方的细节;
- 复用:分层之后可以做到代码或功能的复用;
- 扩展性:分层架构可以让代码更容易横向扩展
在计算机领域现有最典型的分层架构设计就是OSI参考模型和TCP/IP参考模型了。分层模型如下图所示
对于上述的三种分层模式,试想一下,如果没有分层,当一个业务或协议需要改变时,我们只能针对整个系统做修改或扩展。而分层之后,便可以很方便的把不同功能的模块抽离出来,修改对应的模块即可。而且不同层还可以被复用,只要确保按照这个层的协议来处理就可以了。
下面我主要介绍一下java软件应用中的两个常见的分层架构:三层架构和MVC架构
“三层”是指表示层(USL,User Show Layer)、业务逻辑层(BLL,Business Logic Layer)、数据访问层(DAL,Data Access Layer)
各层的位置如下图所示。三层中使用的数据,是通过实体类(Dto用于表示层和业务逻辑层之间的数据传递,entity用于存储数据库表对应的对象,vo用于存储返回封装数据的对象)来传递的。实体类一般放在pojo包下
数据访问层也称为持久层,位于三层中的最下层,用于对数据进行处理。该层中的方法一般都是“原子性”的,即每个方法都不可再分。比如,可以在DAL层中实现数据的增删改查操作,而增、删、改、查四个操作是非常基本的功能,都是不能再拆分的。
在程序中,DAL一般写在dao包中,包里面的类名也是以“Dao”结尾。(有的项目中也把DAL写在Mapper包中,类名以'Mapper')如StudentDao.java、DepartmentDao.java、NewsDao.java等;换句话说,在程序中,DAL是由dao包中的多个“类名Dao.java”组成。每个“类名Dao.java”类,就包含着对该“类名”的所有对象的数据操作,如StudentDao.java中包含对Student对象的增、删、改、查等数据操作,DepartmentDao.java中包含对Department对象的增、删、改、查等数据操作。
位于三层中的中间层(DAL与USL中间),起到了数据交换中承上启下的作用,用于对业务逻辑的封装。BLL的设计对于一个支持可扩展的架构尤为关键,因为它扮演了两个不同的角色。对于DAL而言,它是调用者;对于USL而言,它是被调用者。依赖与被依赖的关系都纠结在BLL上。
使用上,就是对DAL中的方法进行“组装”。比如,该层也可以实现对Student对象的增删改查,但与DAL不同的是,BLL中的增、删、改、查不再是 “原子性”的功能,而是包含了一定的业务逻辑。比如该层中的“删”不再像DAL中那样仅仅实现“删”,而是在“删”之前要进行业务逻辑的判断:先查找该学生是否存在(即先执行DAL层的“查”),如果存在才会真正地“删”(再执行DAL层的“删”),如果该学生不存在则应该提示错误信息。即BLL中的“删”,应该是“带逻辑的删”(即先“查”后“删”),也就是对DAL中的“查”和“删”两个方法进行了“组装”。
在程序中,BLL一般写在service包(或biz包)中,包里面的类名也是以“Service(或Biz)”结尾,如StudentService.java、DepartmentService.java、NewsService等。换句话说,在程序中,BLL是由service包中的多个“类名Service.java”组成。每个“类名Service.java”类,就包含着对该“类名”的对象的业务操作,如StudentService.java中包含对Student对象的“带逻辑的删”、“带逻辑的增”等业务逻辑操作,DepartmentService.java中包含对所有Department对象的“带逻辑的删”、“带逻辑的增”等业务逻辑操作。
位于三层中的最上层,用于显示数据和接收用户输入的数据,为用户提供一种交互式操作的界面。USL又分为“USL前台代码”和“USL后台代码”,其中“USL前台代码”是指用户能直接访问到的界面,一般是程序的外观(如html文件、JSP文件等),类似于MVC模式中的“视图”;“USL后台代码”是指用来调用业务逻辑层的JAVA代码(如Servlet),类似于MVC模式中的“控制器”。表示层前台代码一般放在WebContent目录下,而表示层后台代码目前放在servlet包下。
MVC架构是软件工程中常见的一种软件架构模式,该模式把软件系统(项目)分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。分层模型图如下
先简要介绍一下MVC架构各个组件的含义
- 模型(Model):后端,包含了所有数据逻辑
- 视图(View):前端界面或 GUI
- 控制器(Controller):应用的大脑,控制数据如何展示
- 职责:模型负责处理应用程序的数据逻辑。
- 具体功能:
- 封装应用程序的数据结构和业务规则。
- 提供数据的读取、修改和存储等操作接口。
- 处理数据的获取、处理、验证等具体逻辑。
- 与数据存储层进行交互,实现数据的持久化。
- 职责:视图负责用户界面的展示。
- 具体功能:
- 显示模型中的数据给用户,以便用户可以看到应用程序中的信息。
- 提供一种用户友好的界面,使用户能够与应用程序进行交互。
- 根据模型的变化更新显示的内容,确保视图与数据保持同步。
- 通常不处理数据的具体操作,而是通过控制器来调用模型进行处理。
- 职责:控制器负责处理用户的输入和协调模型与视图之间的交互。
- 具体功能:
- 接收来自视图的用户输入,如按钮点击、表单提交等。
- 根据用户的输入来调用相应的模型方法,处理数据的读取、修改等操作。
- 更新模型中的数据,并通知视图进行相应的更新展示。
- 处理用户输入的验证和错误处理,确保数据的正确性和一致性
下面是MVC分层架构模型的一个简单应用
我们将创建一个作为模型的 Student 对象。StudentView 是一个把学生详细信息输出到控制台的视图类,StudentController 是负责存储数据到 Student 对象中的控制器类,并相应地更新视图 StudentView。
MVCPatternDemo,我们的演示类使用 StudentController 来演示 MVC 模式的用法。
创建模型
public class Student {
private String rollNo;
private String name;
public String getRollNo() {
return rollNo;
}
public void setRollNo(String rollNo) {
this.rollNo = rollNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
创建视图
public class StudentView {
public void printStudentDetails(String studentName, String studentRollNo){
System.out.println("Student: ");
System.out.println("Name: " + studentName);
System.out.println("Roll No: " + studentRollNo);
}
}
创建控制器
public class StudentController {
private Student model;
private StudentView view;
public StudentController(Student model, StudentView view){
this.model = model;
this.view = view;
}
public void setStudentName(String name){
model.setName(name);
}
public String getStudentName(){
return model.getName();
}
public void setStudentRollNo(String rollNo){
model.setRollNo(rollNo);
}
public String getStudentRollNo(){
return model.getRollNo();
}
public void updateView(){
view.printStudentDetails(model.getName(), model.getRollNo());
}
}
使用 StudentController 方法来演示 MVC 设计模式的用法。
public class MVCPatternDemo {
public static void main(String[] args) {
//从数据库获取学生记录
Student model = retrieveStudentFromDatabase();
//创建一个视图:把学生详细信息输出到控制台
StudentView view = new StudentView();
StudentController controller = new StudentController(model, view);
controller.updateView();
//更新模型数据
controller.setStudentName("John");
controller.updateView();
}
private static Student retrieveStudentFromDatabase(){
Student student = new Student();
student.setName("Robert");
student.setRollNo("10");
return student;
}
}
执行程序,输出结果:
Student:
Name: Robert
Roll No: 10
Student:
Name: John
Roll No: 10
MVC架构与三层架构的关系图如下