目录

一、三层架构 \ 四层架构

二、MVC架构模式

三、MVVM架构模式

四、DDD(领域驱动设计)

五、Web架构设计总结

六、三层架构+MVC的实践

七、小结


一、三层架构 \ 四层架构

三层架构:后端代码职责分层(Controller + Service + Dao)。

  • 表现层(Controller):接收请求、返回结果
  • 业务逻辑层(Service):写业务规则
  • 数据访问层(Dao \ Mapper):操作数据库

作用:把代码按职责分开,不乱。

适用:简单项目、管理系统、CRUD为主。

四层架构:在三层基础上拆分得更细(适合复杂项目)。

简单扩展

  • 表现层(Controller):接收请求、返回结果
  • 业务逻辑层(Service):写业务规则
  • 数据访问层(Dao \ Mapper):操作数据库
  • 公共层(Common):存放工具类等

DDD标准四层

  • 接口层
  • 应用层
  • 领域层
  • 基础设施层

作用:项目变大后,职责更清晰,避免Service太臃肿。

二、MVC架构模式

MVC:请求处理模型(接收请求 → 处理 → 返回)。

三部分

  • Controller:接收请求
  • Model:模型
  • View:返回结果(页面 \ 数据)

三、MVVM架构模式

MVVM:View 变 → ViewModel 自动变;ViewModel 变 → View 自动刷新。

三部分

  • View(页面)
  • ViewModel(状态 \ 命令)
  • Model(数据源)

核心:双向绑定

注意:MVVM用于前端(网页、APP),后端不用。

四、DDD(领域驱动设计)

DDD:复杂业务设计思想(领域模型为核心),不是分层,也不是模式。

核心

  • 业务为核心
  • 把业务抽象成领域模型
  • 解决复杂业务(电商、金融、中台)

五、Web架构设计总结

架构 类型 作用 前后端 复杂度
三层 分层 代码职责拆分 后端
四层 分层 更细致的代码职责拆分 后端
MVC 架构模式 处理请求流程 后端
MVVM 架构模式 界面、数据分离 前端
DDD 设计思想 复杂业务建模 后端

注意:实际开发怎么选?

  • 简单管理系统 → 三层 + MVC
  • 前后端分离 → MVVM(前端) + 三层(后端)
  • 复杂业务系统 → DDD + 四层架构

以上是经验之谈,实际使用还是要实事求是!

六、三层架构+MVC的实践

创建数据库

create database web_study;
 
use web_study;

创建数据表

CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
`password` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
);

给数据表添加数据

INSERT INTO `user` VALUES
(1,'bxh','123456'),
(2,'lxh','234567'),
(3,'hxj','345678'),
(4,'qxm','456789'),
(5,'lxm','567890');

这里建议小白严格按照步骤执行

mvc包下的entity包下的user代码

package WebStudy.mvc.entity

// 用户类
// MVC 的 M → Model(数据模型)
public class User {
    private var _id: Int64 = 0
    private var _username: String = ''
    private var _password: String = ''

    // 编号
    public mut prop id: Int64 {
        get() { this._id }
        set(v) { this._id = v }
    }

    // 用户名
    public mut prop username: String {
        get() { this._username }
        set(v) { this._username = v }
    }

    // 密码
    public mut prop password: String {
        get() { this._password }
        set(v) { this._password = v }
    }
}

mvc包下的mapper包下的user_mapper代码

package WebStudy.mvc.mapper

import std.database.sql.*
import std.collection.*
import mariadb.cdbc.*
import WebStudy.mvc.entity.*

// 用户数据访问层
// 只负责获取数据库里面的数据,不负责业务逻辑
// 对应 三层架构 → Mapper(数据访问层)
public class UserMapper { 

    // 获取用户列表
    public func getUserList(): ArrayList<User> {
        // 用户列表
        let userList = ArrayList<User>()

        // 创建驱动
        let driver = DriverManager.getDriver('mariadb').getOrThrow()
        // 数据库的链接
        let url = 'mariadb://127.0.0.1:3306'
        // 数据库用户
        let username = ('username', 'root')
        // 数据库密码
        let password = ('password', 'YGBG372S1')
        // 需要连接数据库
        let database = ('database', 'web_study')
        // 启动驱动获取数据资源
        let dataSource = driver.open(url, [username, password, database])
        // 创建连接
        let connection = dataSource.connect()
    
        let sql = 'select * from user'
        let statement = connection.prepareStatement(sql)
        let resultSet = statement.query()
        
        while (resultSet.next()) {
            // 单个用户
            let user = User()
            user.id = resultSet.get<Int64>(1)
            user.username = resultSet.get<String>(2)
            user.password = resultSet.get<String>(3)
            userList.add(user)
        }

        // 释放资源
        resultSet.close()
        statement.close()
        connection.close()
        dataSource.close()
        return userList
    }

    // 登录
    // uname: 用户名
    // pwd: 密码
    public func login(uname: String, pwd: String): User {
        // 用户实体
        let user = User()

        // 创建驱动
        let driver = DriverManager.getDriver('mariadb').getOrThrow()
        // 数据库的链接
        let url = 'mariadb://127.0.0.1:3306'
        // 数据库用户
        let username = ('username', 'root')
        // 数据库密码
        let password = ('password', 'YGBG372S1')
        // 需要连接数据库
        let database = ('database', 'web_study')
        // 启动驱动获取数据资源
        let dataSource = driver.open(url, [username, password, database])
        // 创建连接
        let connection = dataSource.connect()
    
        let sql = 'select * from user where username=? and password=?'
        let statement = connection.prepareStatement(sql)
        statement.set<String>(1, uname)
        statement.set<String>(2, pwd)
        let resultSet = statement.query()
        
        while (resultSet.next()) {
            user.id = resultSet.get<Int64>(1)
            user.username = resultSet.get<String>(2)
            user.password = resultSet.get<String>(3)
        }

        // 释放资源
        resultSet.close()
        statement.close()
        connection.close()
        dataSource.close()
        return user
    }
}

mvc包下的service包下的user_service代码

package WebStudy.mvc.service

import WebStudy.mvc.entity.*
import WebStudy.mvc.mapper.*

// 用户业务逻辑层
// 负责数据的业务逻辑处理,不负责数据的请求转发
// 三层架构 → Service(业务逻辑层)
public class UserService {
    // 用户数据访问
    private let userMapper = UserMapper()

    // 获取用户列表
    public func getUserList(): String {
        // 获取用户列表
        let userList = this.userMapper.getUserList()
        var userListStr = """
            序号&nbsp;&nbsp;&nbsp;&nbsp;
            用户名&nbsp;&nbsp;&nbsp;&nbsp;
            密码<br>
        """
        for (user in userList) {
            userListStr += """
                ${user.id}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                ${user.username}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                ${user.password}<br>
            """
        }
        return userListStr
    }

    // 登录
    // uname: 用户名
    // pwd: 密码
    public func login(uname: String, pwd: String): Bool {
        // 用户实体
        let user = this.userMapper.login(uname, pwd)
        if (uname == user.username && pwd == user.password) {
            println('登录成功')
            return true
        } else {
            println('用户名或密码错误, 登录失败')
            return false
        }
    } 
}

mvc包下的controller包下的user_controller代码

package WebStudy.mvc.controller

import WebStudy.mvc.service.*

// 用户控制器
// 接收请求、参数校验、调用 Service、返回结果
// MVC 的 C → Controller
public class UserController {
    // 用户业务逻辑
    private let userService = UserService()

    // 获取用户列表
    public func getUserList(): String {
        // MVC 的 V → View
        return this.userService.getUserList()
    }

    // 登录
    // uname: 用户名
    // pwd: 密码
    // return 
    public func login(uname: String, pwd: String): Bool {
        // 参数校验
        if (uname == '' || pwd == '') {
            // 记录日志
            println('用户名或密码为空')
            // MVC 的 V → View
            return false
        } else {
            // MVC 的 V → View
            return this.userService.login(uname, pwd)
        }
    }

    // 登录页面
    public func loginPage(): String {
        // MVC 的 V → View
        return """
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
                <title>登录表单</title>
            </head>
            <body>
                <h2>用户登录</h2>
                <!-- 登录表单 -->
                <form action="http://localhost:8080/doLogin" method="post">
                    <!-- 用户名输入框 -->
                    <div>
                        <label>用户名:</label>
                        <input type="text" name="username" required>
                    </div>
                    <br>

                    <!-- 密码输入框 -->
                    <div>
                        <label>密码:</label>
                        <input type="password" name="password" required>
                    </div>
                    <br>

                    <!-- 提交按钮 -->
                    <input type="submit" value="登录">
                </form>
            </body>
            </html>
        """
    }
}

mvc包下的mvc代码

package WebStudy.mvc

import stdx.net.http.*
import WebStudy.mvc.controller.*

// 启动服务
public func startServer() {
    // 用户控制器
    let userController = UserController()

    // 服务器
    let server: Server = ServerBuilder().addr('127.0.0.1').port(8080).build()

    // 登录页
    let login = FuncHandler { httpContext : HttpContext =>
        httpContext.responseBuilder.header('Content-Type', 'text/html;charset=UTF-8')
        httpContext.responseBuilder.body(userController.loginPage())
    }

    // 登录处理
    let doLogin = FuncHandler { httpContext : HttpContext =>
        let form = httpContext.request.form
        let username = form.get('username') ?? ''
        let password = form.get('password') ?? ''
        let isOk = userController.login(username,password)

        if(isOk){
            // 成功跳/userList
            httpContext.responseBuilder.status(302)
            httpContext.responseBuilder.header('Location', '/userList')
        }else{
            // 失败跳/failure
            httpContext.responseBuilder.status(302)
            httpContext.responseBuilder.header('Location', '/failure')
        }
    }

    // 失败页
    let failure = FuncHandler { httpContext : HttpContext =>
        httpContext.responseBuilder.header('Content-Type', 'text/html;charset=UTF-8')
        httpContext.responseBuilder.body('用户名或密码错误,登录失败')
    }

    // 用户列表页
    let userList = FuncHandler { httpContext : HttpContext =>
        httpContext.responseBuilder.header('Content-Type', 'text/html;charset=UTF-8')
        httpContext.responseBuilder.body(userController.getUserList())
    }

    // 统一注册固定路由
    server.distributor.register('/login', login)
    server.distributor.register('/doLogin', doLogin)
    server.distributor.register('/userList', userList)
    server.distributor.register('/failure', failure)
    
    println('Web服务已启动...')
    server.serve()
}

main代码

package WebStudy

import WebStudy.mvc.startServer

main(): Unit {
    startServer()
}

在浏览器访问:http://localhost:8080/login

运行结果

七、小结

本章为大家详细的介绍了Web架构设计的内容,下一章为大家介绍Cookie、Session、Token和JWT的内容。最后,创作不易,如果大家觉得我的文章对学习仓颉Web基础编程有帮助的话,就动动小手,点个免费的赞吧!收到的赞越多,我的创作动力也会越大哦,谢谢大家🌹🌹🌹!!!

Logo

一站式 AI 云服务平台

更多推荐