当前位置: 首页 > news >正文

Flutter 项目结构该如何设计,才能支撑长期迭代

网罗开发(小红书、快手、视频号同名)

大家好,我是展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


文章目录

    • 前言
    • 常见 Flutter 项目结构对比
    • 页面级和业务级模块怎么划分
    • 可扩展的目录规范
    • 实际项目演进中的取舍
    • 总结

前言

很多 Flutter 项目一开始目录挺整齐,按「页面」「模型」「服务」一分,看起来挺好维护。可随着功能越加越多,改一处要动好几个文件夹、新人看半天不知道从哪下手、加个新需求总怕踩到老代码的雷。本质上是结构没按「长期迭代」来设计,只满足了「当下能跑」。要支撑长期迭代,就得在目录划分、模块边界和扩展规范上想清楚,让每个改动都有明确归属,新人也能按图索骥。

下面从常见结构对比、页面级和业务级怎么切、可扩展的目录规范、以及实际演进中的取舍几方面说一下。

常见 Flutter 项目结构对比

最常见的有两种思路:按「类型」分(type-first)和按「功能/业务」分(feature-first)。

按类型分,就是大家熟悉的lib/models/views/services/utils/这种。所有模型放一起、所有页面放一起、所有接口放一起。好处是刚上手简单,找「所有接口」或「所有页面」很快。问题在于:一个业务(比如「订单」)的模型、页面、接口、状态会散在四个目录里,改一个需求要到处跳,职责也容易混——services里既有订单接口又有用户接口,时间一长就变成大杂烩,新人很难判断「这段逻辑该放哪」。

按功能/业务分(Feature First),则是按业务域或功能块建目录,每个功能块里再放自己的页面、模型、接口、状态。例如lib/features/order/lib/features/user/,每个 feature 下面再分screens/widgets/models/services/等。这样「订单相关」的改动基本都在order下完成,边界清晰,新人接手也容易:先找 feature,再在 feature 里找具体文件。代价是前期要定好「哪些算一个 feature」,避免 feature 划分过细或过粗。

实际项目里,往往不会非此即彼:核心、会长期演进的业务用 Feature First真正全局的通用能力(如网络封装、路由、通用组件)单独抽成 shared 或 core,这样既避免「全按类型」导致的扩散,也避免「全按 feature」导致公共层缺失。

页面级和业务级模块怎么划分

「模块」可以按粒度拆成两种:页面级和业务级。

页面级以「一个或一组相关页面」为单位。比如「订单列表」「订单详情」「订单创建」算一个订单模块,里面主要是 UI、页面状态和该页用到的接口。适合功能相对独立、复用面不大的场景。划分时建议:一个模块一个目录,里面再按screens/widgets/providers/bloc/等分层,避免一个文件上千行。

业务级比页面大一层,是「一整块业务」:订单从列表、详情、创建、支付、售后都算订单业务,可能跨多个页面、甚至多个 Tab。业务级模块里会包含多个页面级子模块,以及该业务共用的模型、领域逻辑、接口。划分业务级的意义在于:把「会一起变、一起发版」的东西收拢,减少跨模块的随意依赖。比如订单和商品是两条业务线,订单模块可以依赖「商品」的少量接口或模型,但不要反过来让订单逻辑散进商品模块。

实践中:先按业务级划出几个大目录(如 order、user、product),再在业务内部按页面或子功能划子目录。这样既不会一上来就几十个平级目录,也不会所有代码挤在少数几个文件夹里。

可扩展的目录规范

要支撑长期迭代,目录不能只满足「现在」,还要约定「以后怎么加」。建议定几条简单规范:

第一,统一命名和层级。例如每个 feature 下都允许有screens/widgets/models/services/(或你项目用的分层),新增时只在这几类里加,不随意在 feature 根目录堆新名字。这样任何人一看就知道「新页面放 screens,新接口放 services」。

第二,公共能力单独成层。如lib/core/lib/shared/放网络、路由、存储、通用 UI 组件、常量等。feature 只依赖 core/shared,不互相依赖;core 不依赖具体 feature。这样以后加新 feature 或换掉某个业务,不会牵一发动全身。

第三,约定「入口」。每个 feature 尽量有一个index.dart或明确入口文件,对外只 export 需要被路由或其它模块引用的部分,内部实现细节不暴露。这样依赖关系清晰,重构时也容易缩小影响面。

第四,文档化。在项目根目录或lib/下放一个简单的STRUCTURE.md,说明「业务模块有哪些、公共层放什么、新加一个 feature 要建哪些目录、命名约定」。新人按文档操作即可,减少「随便建个文件夹」的随意性。

一个可参考的目录示例(按上述规范收敛后)可以长这样:

lib/ ├── core/ # 公共层,被各 feature 依赖 │ ├── network/ │ ├── router/ │ ├── storage/ │ └── widgets/ # 通用按钮、弹窗等 ├── features/ │ ├── order/ │ │ ├── screens/ # 订单列表、详情、创建等页 │ │ ├── widgets/ # 订单相关卡片、表单等 │ │ ├── models/ │ │ ├── services/ │ │ └── index.dart # 只 export 路由需要的 Page、对外模型 │ ├── user/ │ │ ├── screens/ │ │ ├── widgets/ │ │ ├── models/ │ │ ├── services/ │ │ └── index.dart │ └── product/ │ └── ... └── app.dart # 入口,注册路由、主题等

解析:core里不放业务逻辑,只放「大家都要用」的能力,这样新加或替换某个 feature 时,不会动到 core。每个 feature 内部结构一致(screens/widgets/models/services),新人加「订单下的新页」就知道去order/screens/新建文件。index.dart只对外暴露路由用到的页面和少量对外模型,避免其它模块直接import 'order/xxx/internal.dart',以后改内部实现不会波及全局。按这种约定扩展,长期迭代时改动的范围更容易控制。

实际项目演进中的取舍

真实项目里,很少能从零就按「理想结构」来,多半是边做边收拢。

初期:功能少、人少,用类型分(models/views/services)就能跑。这时不必强行上 Feature First,但可以约定:新增功能时,尽量在一个「功能子目录」下集中放(例如views/order/services/order/),为以后拆成独立 feature 留余地。

中期:功能多了、改一处动多处的情况开始出现,就可以选 1~2 个最核心、最常改的业务,先拆成 feature 目录,把相关页面、模型、接口都迁进去。其它暂时保持原样,用「新代码按新结构、老代码逐步迁」的方式演进,避免一次性大重构。

长期:核心业务都进 feature,公共能力稳定在 core/shared,再配合「入口 export」和依赖方向约定(feature 不互相依赖),就能比较稳地支撑长期迭代。遇到「这段到底算哪个 feature」的争议,以「谁改得多、谁负责」为准来归属,再慢慢用边界清晰化。

总结

Flutter 项目要支撑长期迭代,结构上建议:用 Feature First 收拢业务,用 core/shared 收拢公共能力;区分清楚页面级和业务级模块,先按业务划大目录再在内部按页面或子功能细分;并约定好目录层级、命名、入口和依赖方向,再配一份简短的结构说明文档。这样初期不会过度设计,后期也有清晰的扩展路径,改起来敢动、新人接手成本也会低很多。

http://www.jsqmd.com/news/421581/

相关文章:

  • 企业短信平台选云厂商还是垂直短信平台? - Qqinqin
  • 2026年重庆公办职高精选 实力出众口碑优良 适配各类学子发展 升学就业有保障 - 深度智识库
  • 2026年 编织袋厂家推荐排行榜:饲料/化肥/大米/种子/粮食/玉米/腻子粉/砂浆/化工/矿山编织袋,专业定制与耐用品质之选 - 品牌企业推荐师(官方)
  • 记一次vs中无法找到win sdk的问题
  • 苏剑林苏神科学空间:一个数学极客的十六年技术坚守
  • 国产恒温恒湿试验箱怎么选?泰美科昆山研发+襄阳生产全维度解析 - 博客万
  • 商场、办公楼与酒店香氛香薰推荐,解锁商业空间嗅觉密码 - 包罗万闻
  • 预算有限怎么选:十大留学机构分级服务指南 - 博客湾
  • 2026年如何从砖机公司排名中选择知名的路沿石砖机厂家? - 睿易优选
  • 代理模式——基本介绍
  • 2025年货架选购攻略:哪些功能是必备?重型货架/仓储货架/隔板货架/层板货架/贯通式货架,货架源头厂家排行榜 - 品牌推荐师
  • 解决连接无法继续,因为未启用身份验证,并且远程计算机需要启用身份验证以进行连接
  • 十大香港留学机构!保障港申材料翻译的专业性 - 博客湾
  • 二元运算符
  • 为什么你在百度排第一,客户却选了竞争对手?
  • Continual-MEGA—Arxiv2026—阅读笔记
  • 2026年重庆卫校哪家靠谱?实力强劲口碑优良 适配不同学子需求 - 深度智识库
  • Python为何要使用代理IP?
  • 2026年 环境监测仪器厂家推荐排行榜:光合作用监测仪、气体监测仪、水质监测仪等专业设备实力品牌深度解析 - 品牌企业推荐师(官方)
  • 2026年有实力的活性氧化铝除氟剂,活性氧化铝干燥剂厂家选购参考指南 - 品牌鉴赏师
  • 2026年口碑好的分子筛干燥剂厂家选购参考名录 - 品牌鉴赏师
  • LeetCode 394 字符串解码
  • 2026年 南通竞价托管外包服务商推荐榜:专业搜索引擎竞价推广与外包代操作一站式解决方案 - 品牌企业推荐师(官方)
  • 尚帝传媒私护品牌战略合作|GEO加持,破解行业传播痛点 - 品牌之家
  • dpdk之从多队列 DMA 到 Burst 批量处理
  • STC8G内置IRC 32KHz的试用
  • AI大模型36个关键术语
  • 港申成功有捷径:TOP10 香港留学中介来帮忙 - 博客湾
  • 最容易胖肚子的一种食物!揭秘:你吃的,决定了你的腰围!
  • 2026年评价高的固体次氯酸钠厂家选择指南 - 品牌鉴赏师