尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

拒绝“面条代码”!Flutter 校园项目的“三层架构”实战

拒绝“面条代码”!Flutter 校园项目的“三层架构”实战
📅 发布时间:2026/6/18 15:30:29

拒绝“面条代码”!Flutter 校园项目的“三层架构”实战

作为一名计算机专业的学生,你是否遇到过这种情况:
为了赶课程设计或hackathon,在 StatefulWidget 的 build 方法里直接写 Dio.get ,把网络请求、JSON解析、UI更新全都堆在一起。结果项目刚写到一半,代码就乱成了“意大利面”,改一个接口字段要在几百行代码里找半天,队友看了想打人。

最近重构校园跑腿 App 时,我痛定思痛,引入了三层架构(Repository + ViewModel + UI)的思想,配合 GetX 状态管理,终于把代码理顺了。这篇文章,我想分享这套适合大学生项目的**“清爽开发模式”**。

一、 什么是“三层架构”?

简单来说,就是把我们的代码像切蛋糕一样分成三块,各司其职:

  1. 数据层 (Repository/Model):只管“拿数据”。负责对接后端 API,解析 JSON,或者读写本地缓存。它不知道谁在调用它。
  2. 逻辑层 (ViewModel/Controller):只管“处理数据”。负责接收 UI 的指令,调用数据层,处理业务逻辑(比如判断登录状态),然后通知 UI 更新。
  3. 表现层 (UI/View):只管“展示”。它不包含复杂逻辑,只负责把 ViewModel 给的数据画在屏幕上,并在用户点击按钮时通知 ViewModel。

二、 代码实战:校园登录功能的“整容”过程

下面我用一个最常见的**“校园账号登录”**功能,展示如何用这套架构重写代码。

第一步:定义数据模型 (Model)

先定义好数据的结构,这里使用 json_serializable 插件自动生成(强烈推荐,别手写 fromJson )。

dart

// models/user.dart
import ‘package:json_annotation/json_annotation.dart’;

part ‘user.g.dart’;

@JsonSerializable()
class User {
final String studentId;
final String name;
final String token;

User({required this.studentId, required this.name, required this.token});

// 自动生成的代码
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}

第二步:数据仓库 (Repository)

专门处理网络请求,这里我使用 Dio 。

dart

// repositories/auth_repository.dart
import ‘package:dio/dio.dart’;
import ‘…/models/user.dart’;

class AuthRepository {
final Dio _dio = Dio();

// 登录请求,只关心参数和返回值,不关心UI
Future login(String id, String password) async {
try {
final response = await _dio.post(
“https://api.campus.com/login”,
data: {“student_id”: id, “password”: password},
);
// 直接返回模型对象,让调用者省心
return User.fromJson(response.data[‘data’]);
} catch (e) {
// 抛出异常,让上层处理
throw Exception(“登录失败: $e”);
}
}
}

第三步:业务逻辑 (ViewModel/Controller)

这是核心,我使用 GetxController 。它像一个中间人,隔离了 UI 和数据。

dart

// controllers/login_controller.dart
import ‘package:get/get.dart’;
import ‘…/repositories/auth_repository.dart’;
import ‘…/models/user.dart’;

class LoginController extends GetxController {
// 1. 依赖注入仓库
final AuthRepository _repo = AuthRepository();

// 2. 定义可观测状态(UI 可以监听这些变量)
var isLoading = false.obs;
var errorMessage = “”.obs;

// 3. 业务方法(UI 调用这个方法)
Future handleLogin(String id, String pwd) async {
isLoading.value = true;
errorMessage.value = “”;

try { User user = await _repo.login(id, pwd); // 登录成功后的逻辑:保存 Token、跳转页面 GetStorage().write('token', user.token); Get.offAllNamed('/home'); // 路由跳转 } catch (e) { errorMessage.value = e.toString(); } finally { isLoading.value = false; }

}
}

第四步:清爽的 UI 层

UI 层现在变得非常干净,没有任何 async/await 网络代码。

dart

// pages/login_page.dart
import ‘package:flutter/material.dart’;
import ‘package:get/get.dart’;
import ‘…/controllers/login_controller.dart’;

class LoginPage extends StatelessWidget {
// 获取控制器
final LoginController _controller = Get.put(LoginController());

@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(20),
child: Column(
children: [
TextField(
decoration: InputDecoration(labelText: “学号”),
// … 省略控制器绑定
),
TextField(
decoration: InputDecoration(labelText: “密码”),
obscureText: true,
),
SizedBox(height: 20),
// 监听状态变化
Obx(() => _controller.isLoading.value
? CircularProgressIndicator()
: ElevatedButton(
onPressed: () => _controller.handleLogin(“2023001”, “123456”),
child: Text(“登录”)
)
),
// 错误提示
Obx(() => Text(
_controller.errorMessage.value,
style: TextStyle(color: Colors.red),
))
],
),
),
);
}
}

三、 这样做的好处(为什么要折腾?)

  1. 代码复用:如果我在“个人中心”也需要用到登录接口,直接调用 AuthRepository 即可,不用复制粘贴代码。
  2. 便于测试:如果后端接口挂了,我想测试 UI 表现,只需要在 ViewModel 里模拟一个返回数据,完全不用动 UI 代码。
  3. 面试亮点:当面试官问你“如何处理网络请求”时,如果你能说出“我会分层处理,使用 Repository 模式隔离数据源”,这比说“我直接在 initState 里写 Dio.get ”要高级得多。

四、 给同学们的建议

对于校园项目,我们不需要追求 Google 官方那套庞大的 BLoC 模式(学习曲线太陡),GetX + 简单的 Repository 分层 是目前性价比最高的方案。

下次做课设或大作业时,试着把网络请求抽离出来,你会发现你的代码结构会变得像教科书一样漂亮。

结语:
技术的成长往往不是看你会多少炫酷的特效,而是看你写的代码是否“高内聚、低耦合”。希望这篇文章能帮你摆脱“代码洁癖”的困扰,写出让自己和队友都舒服的 Flutter 代码!

相关新闻

  • Anthropic文章-打造高性能智能体 学习笔记
  • 英语_阅读_Happiness_待读
  • 串口通讯的android 封装开箱即用!提供源代码!

最新新闻

  • PiliPlus完全指南:打造你的专属B站开源客户端
  • 基于六维超混沌与DNA编码的图像加密算法实现与解析
  • 再生资源行业实力测评 海峰梦再生资源口碑价格透明推荐 - 工业品牌热点
  • 如何快速构建智能标注系统:OpenMMLab MMPose的完整指南
  • vscode-edge-devtools 设备模拟功能详解:响应式设计调试技巧
  • Loop:优雅掌控macOS窗口管理的终极解决方案

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号