网站建设个人简历,视频加字幕软件app,网站开发 工程师 类型,视频网站是用什么框架做的网罗开发#xff08;小红书、快手、视频号同名#xff09;大家好#xff0c;我是 展菲#xff0c;目前在上市企业从事人工智能项目研发管理工作#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术#xff0c;包括iOS、前端、Harmony OS、Java、Python等方…网罗开发小红书、快手、视频号同名大家好我是展菲目前在上市企业从事人工智能项目研发管理工作平时热衷于分享各种编程领域的软硬技能知识以及前沿技术包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。图书作者《ESP32-C3 物联网工程开发实战》图书作者《SwiftUI 入门进阶与实战》超级个体COC上海社区主理人特约讲师大学讲师谷歌亚马逊分享嘉宾科技博主华为HDE/HDG我的博客内容涵盖广泛主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告同时也会提供产品优缺点分析、横向对比并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。展菲您的前沿技术领航员 大家好我是展菲 全网搜索“展菲”即可纵览我在各大平台的知识足迹。 公众号“Swift社区”每周定时推送干货满满的技术长文从新兴框架的剖析到运维实战的复盘助您技术进阶之路畅通无阻。 微信端添加好友“fzhanfei”与我直接交流不管是项目瓶颈的求助还是行业趋势的探讨随时畅所欲言。 最新动态2025 年 3 月 17 日快来加入技术社区一起挖掘技术的无限潜能携手迈向数字化新征程文章目录前言不同技术栈的结构演进路径Flutter从扁平到混乱前端强模块化但依赖复杂iOS模块清晰但复用成本高Flutter 项目拆分的真实难点文件组织方式的问题依赖关系的隐式耦合状态管理的分散借鉴前端 Feature 模型模块间的依赖管理一套可扩展目录实践核心原则目录结构设计模块初始化路由管理实际应用中的注意事项避免过度拆分共享代码的管理测试的组织总结前言最近在做一个 Flutter 项目重构发现了一个很有意思的现象项目初期的时候目录结构看起来很干净所有文件都整整齐齐地放在lib目录下按功能分类一目了然。但项目做到后期想要改个功能或者加个新特性却发现代码耦合严重牵一发动全身改起来特别费劲。这让我想起了前端和 iOS 的项目结构。前端项目通常一开始就做模块化虽然初期看起来复杂但后期扩展容易。iOS 项目模块划分清晰但复用成本高。Flutter 项目则相反初期简单后期复杂。今天我们就来聊聊 Flutter 项目结构为什么会看起来干净后期却很难改以及如何借鉴前端和 iOS 的经验设计一套可扩展的目录结构。不同技术栈的结构演进路径不同的技术栈在项目结构上有不同的演进路径理解这些路径可以帮助我们更好地设计 Flutter 项目结构。Flutter从扁平到混乱Flutter 项目初期通常采用扁平化的目录结构所有文件都放在lib目录下按功能分类lib/ ├── models/ │ ├── user.dart │ └── product.dart ├── views/ │ ├── home_page.dart │ └── detail_page.dart ├── services/ │ ├── api_service.dart │ └── storage_service.dart └── utils/ ├── constants.dart └── helpers.dart这种结构在小项目中确实很清晰每个目录的职责明确。但随着项目规模增大问题就来了文件越来越多models目录下可能有几十个文件找文件变得困难依赖关系复杂views依赖models和servicesservices依赖models形成复杂的依赖网络功能边界模糊一个功能相关的代码分散在多个目录中修改时需要跨目录操作前端强模块化但依赖复杂前端项目通常采用 Feature First 的目录结构按功能模块组织代码src/ ├── features/ │ ├── user/ │ │ ├── components/ │ │ ├── services/ │ │ ├── models/ │ │ └── index.ts │ ├── product/ │ │ ├── components/ │ │ ├── services/ │ │ ├── models/ │ │ └── index.ts │ └── order/ │ ├── components/ │ ├── services/ │ ├── models/ │ └── index.ts ├── shared/ │ ├── components/ │ ├── utils/ │ └── services/ └── app.tsx这种结构的优势是功能内聚每个功能模块都是自包含的。但问题也很明显依赖管理复杂模块之间如何共享代码如何避免循环依赖代码重复不同模块可能有相似的逻辑如何复用构建配置复杂需要配置模块路径、别名等iOS模块清晰但复用成本高iOS 项目通常采用模块化的目录结构每个模块都是一个独立的 targetProject/ ├── Core/ │ ├── Network/ │ ├── Storage/ │ └── Utils/ ├── Features/ │ ├── Home/ │ │ ├── View/ │ │ ├── ViewModel/ │ │ └── Model/ │ ├── Profile/ │ │ ├── View/ │ │ ├── ViewModel/ │ │ └── Model/ │ └── Settings/ │ ├── View/ │ ├── ViewModel/ │ └── Model/ └── Resources/ ├── Assets/ └── Localizable/这种结构的优势是模块边界清晰每个模块都可以独立开发和测试。但问题也很明显复用成本高想要复用某个模块需要创建新的 target配置依赖关系编译时间长模块化后编译时间可能会增加团队协作复杂不同模块可能由不同人开发需要协调接口Flutter 项目拆分的真实难点Flutter 项目结构之所以看起来干净后期却很难改主要有几个原因文件组织方式的问题Flutter 的扁平化目录结构在小项目中很好用但在大项目中就会暴露问题。比如我们有一个用户相关的功能涉及到的文件可能包括models/user.dart用户模型views/user_profile_page.dart用户资料页面services/user_service.dart用户服务widgets/user_avatar.dart用户头像组件这些文件分散在不同的目录中想要修改用户功能需要在多个目录之间跳转。而且如果多个功能都用到用户相关的代码依赖关系就会变得复杂。依赖关系的隐式耦合Flutter 项目中的依赖关系往往是隐式的没有明确的模块边界。比如home_page.dart可能直接导入user_service.dart而user_service.dart又依赖api_service.dart。这种隐式依赖在小项目中没问题但在大项目中就会导致循环依赖A 依赖 BB 依赖 CC 又依赖 A测试困难想要测试某个功能需要 mock 很多依赖重构困难想要修改某个模块不知道会影响哪些地方状态管理的分散Flutter 的状态管理通常分散在各个页面中没有统一的管理方式。比如用户信息可能在多个页面中都有状态如果用户信息更新了需要手动同步多个地方的状态。这种分散的状态管理会导致状态不一致不同页面的状态可能不同步难以追踪不知道状态在哪里被修改了难以测试状态和 UI 耦合在一起难以单独测试借鉴前端 Feature 模型前端的 Feature First 模型可以很好地解决 Flutter 项目结构的问题。我们可以将 Flutter 项目也按功能模块组织lib/ ├── features/ │ ├── user/ │ │ ├── data/ │ │ │ ├── models/ │ │ │ └── repositories/ │ │ ├── domain/ │ │ │ ├── entities/ │ │ │ └── use_cases/ │ │ ├── presentation/ │ │ │ ├── pages/ │ │ │ ├── widgets/ │ │ │ └── providers/ │ │ └── user_module.dart │ ├── product/ │ │ ├── data/ │ │ ├── domain/ │ │ ├── presentation/ │ │ └── product_module.dart │ └── order/ │ ├── data/ │ ├── domain/ │ ├── presentation/ │ └── order_module.dart ├── core/ │ ├── network/ │ ├── storage/ │ ├── utils/ │ └── widgets/ └── main.dart这种结构的优势是功能内聚每个功能的所有代码都在一个目录下修改时只需要关注一个目录依赖清晰模块之间的依赖关系通过core目录管理避免循环依赖易于测试每个模块都可以独立测试模块间的依赖管理在 Feature First 模型中模块之间的依赖需要明确管理。我们可以通过以下方式// features/user/user_module.dartclassUserModule{staticvoidconfigure(){// 注册用户相关的依赖GetIt.instance.registerLazySingletonUserRepository(()UserRepositoryImpl(),);}}// features/order/order_module.dartclassOrderModule{staticvoidconfigure(){// 订单模块可以依赖用户模块GetIt.instance.registerLazySingletonOrderRepository(()OrderRepositoryImpl(userRepository:GetIt.instanceUserRepository(),),);}}这样模块之间的依赖关系就很清晰了而且可以避免循环依赖。一套可扩展目录实践基于以上分析我们可以设计一套可扩展的 Flutter 项目目录结构核心原则功能内聚每个功能的所有代码都在一个目录下依赖外置共享的代码放在core目录接口明确模块之间通过接口通信不直接依赖实现目录结构设计lib/ ├── features/ # 功能模块 │ ├── user/ # 用户模块 │ │ ├── data/ # 数据层 │ │ │ ├── models/ │ │ │ ├── repositories/ │ │ │ └── data_sources/ │ │ ├── domain/ # 业务层 │ │ │ ├── entities/ │ │ │ └── use_cases/ │ │ ├── presentation/ # 展示层 │ │ │ ├── pages/ │ │ │ ├── widgets/ │ │ │ └── providers/ │ │ └── user_module.dart │ └── product/ # 产品模块结构相同 ├── core/ # 核心模块 │ ├── network/ # 网络层 │ ├── storage/ # 存储层 │ ├── utils/ # 工具类 │ └── widgets/ # 共享组件 ├── config/ # 配置文件 │ ├── routes.dart │ └── theme.dart └── main.dart模块初始化每个模块都应该有一个初始化方法用于注册依赖// features/user/user_module.dartclassUserModule{staticvoidinit(){// 注册数据源GetIt.instance.registerLazySingletonUserRemoteDataSource(()UserRemoteDataSourceImpl(),);// 注册仓库GetIt.instance.registerLazySingletonUserRepository(()UserRepositoryImpl(remoteDataSource:GetIt.instanceUserRemoteDataSource(),),);// 注册用例GetIt.instance.registerLazySingletonGetUserUseCase(()GetUserUseCase(repository:GetIt.instanceUserRepository(),),);}}路由管理路由应该按模块组织避免集中在一个文件中// features/user/presentation/routes.dartclassUserRoutes{staticconstStringprofile/user/profile;staticconstStringsettings/user/settings;staticRoutedynamicgenerateRoute(RouteSettingssettings){switch(settings.name){caseprofile:returnMaterialPageRoute(builder:(_)UserProfilePage(),);casesettings:returnMaterialPageRoute(builder:(_)UserSettingsPage(),);default:returnMaterialPageRoute(builder:(_)NotFoundPage(),);}}}实际应用中的注意事项采用 Feature First 结构后需要注意以下几点避免过度拆分不是所有功能都需要拆分成独立的模块。如果功能很简单或者多个功能共享很多代码可以考虑合并// 简单功能可以合并features/├── auth/# 认证功能 └── common/# 通用功能多个模块共享共享代码的管理共享代码应该放在core目录而不是某个功能模块中// core/widgets/loading_indicator.dartclassLoadingIndicatorextendsStatelessWidget{// 所有模块都可以使用的加载指示器}// 不要在某个功能模块中定义共享组件// features/user/widgets/loading_indicator.dart ❌测试的组织测试应该和代码结构保持一致test/ ├── features/ │ ├── user/ │ │ ├── data/ │ │ ├── domain/ │ │ └── presentation/ │ └── product/ └── core/总结Flutter 项目结构看起来干净后期却很难改的根本原因在于初期采用扁平化结构没有考虑模块化和依赖管理。随着项目规模增大文件越来越多依赖关系越来越复杂修改就变得困难了。借鉴前端的 Feature First 模型我们可以将 Flutter 项目按功能模块组织每个模块都是自包含的模块之间通过明确的接口通信。这样既能保持代码的清晰又能保证后期的可维护性。当然没有一套结构是完美的关键是要根据项目的实际情况选择合适的结构。小项目可以用扁平化结构大项目应该采用模块化结构。理解不同结构的优缺点可以帮助我们做出更好的选择。