军队中有“军师旅团营”,营是团的组件,师是军的组件。
国家中有“省市县乡村”,村是乡的组件,市是省的组件。
要管理复杂的结构,逐层划分组件是一个很好的方法。
本文探讨的组件化,并非以代码复用为目的。
本文关注于通过组件化,管理比较复杂的工程,提高人效,降低损耗。
问题复杂的工程往往存在如下两个主要问题:
说到代码风格,很多人都知道这个常识。
如果一个函数太长了,需要拆成不同函数。
如果一个类太长了,需要拆成不同类。
如果一个文件太长了,需要拆成不同文件。
同样的,如果我们的项目太大,文件太多,就需要拆分成不同的组件了。
减少耦合如果拆成不同组件后,各个组件仍然有千丝万缕的联系,维护起来仍然会一团乱麻。
我们应当尽量避免组件之间的依赖。减少耦合。
利用router可以很好的解决页面互相跳转时引起的耦合。
后面将会演示如何在flutter中实现通过路由减少耦合。
怎样组织你的代码大军之前见到过一套Android代码“充分”利用了MVP模式。 整个项目下面分了3个目录,M,V,P。 V下面又分 Activities,Views,Adapters,...
虽然逻辑和UI分的很开,但是要修改一个业务或者新加一套功能,需要跨越各个目录,逐一添加代码。
我比较推荐的是下面的划分方法:
+------------------------------------------------+| main frame || +-----------+-----------+-----------+-----+ || | business1 | business2 | business3 | ... | |+--+-----------+-----------+-----------+-----+---++------------------------------------------------+| common |+------------------------------------------------+复制代码
business1,business2,business3,...是不同的业务模块。
例如: 画廊,搜索,课程,推荐,....
这样做的好处是,当你添加代码的时候可以专注于当前业务, 忽略其他业务模块,大大减小了需要维护的代码的范围。
通常产品需求的发展和变化也是按照业务为单位进行的。 比如产品经理想到了一种新的课程模式,这个需求将影响到和课程相关的一些代码。 如果我们的代码本来就已经将课程业务封装在一起的话,修改将都在这个模块内部进行。而不会株连其他部分的代码。
当然我们不是不考虑代码的复用,通常有很多值得复用的代码都是和业务无关的。 和业务无关,也就是说不专属于某个业务,业务A可能会用到,业务B也可能会用到。 这些可复用的业务无关的代码将会方阵上面架构的common部分。
总结一下:Flutter天生就适合组件化,只要你研究的足够深入,就能发现这些特征:
在这里我专门写了一套框架示例: Flutterame
命名含义:Flutterame = Flutter + Frame
准备工欲善其事,必先利其器。
让我们先准备一下.
1. 创建工程flutter create --org top.ovo --platforms ios,android flutterame
想要学习flutter create的更多用法可以看一下我的另一篇文章:玩转flutter create命令,做10倍程序员 其中除了我对 flutter create --help的翻译还有一些其他的奇怪的小技巧。
2. 针对国内网络优化Android编译速度2.1 手动修改android/build.gradle文件。修改前:
repositories { google() jcenter() }复制代码
修改后:
repositories { maven { url 'https://maven.aliyun.com/repository/google'} // google() maven { url 'https://maven.aliyun.com/repository/jcenter'} // jcenter() }复制代码
2.2 用脚本修改bin/optimize_cn_network.py android/复制代码
网速优化详情见:Flutter工程的Android编译网速优化
好了这下你可以愉快的flutter run了。
准备工作完成,接下来我们创建一个组件。
开始实现组件化3. 创建组件假如我们要在项目下的modules/目录下创建名为gallery的模块,我们可以先进入modules目录再用flutter create创建模块
flutter create -t module --org top.ovo gallery复制代码
这里的-t module表示要创建的是一个组件而不是完整的app。
创建的组件目录如下:
.├── .android├── .dart_tool├── .gitignore├── .ios├── .metadata├── .packages├── README.md├── build├── gallery.iml├── gallery_android.iml├── lib│ └── main.dart├── pubspec.lock├── pubspec.yaml└── test复制代码
3.1 组件可以直接运行在当前组件目录中,我们可以直接用flutter run 运行这个组件。 不久你就能看到熟悉的计数器demo页面。 它和一个普通的app没有太大区别。
由此可见,Flutter的开发者充分考虑到了组件化的需求。你不但可以把组件放在app中运行,也可以单独运行组件。
3.2 神奇的“.android” 和 “.ios”如果你仔细观察创建好的目录,你会发现一个有趣的现象:
在app中android和ios目录不见了。取而代之的是两个隐藏目录 “.android” 和 “.ios”。
也就是说这两个目录是隐藏的,默认情况下是不会被添加到git中的。 那如果其他人拉取了这套代码,还能单独运行这个组件吗?
经过实验发现:
如果在没有“.android” 和 “.ios”目录的组件目录中运行flutter run的时候。
Flutter会重新创建“.android” 和 “.ios”目录。
正因为.android目录是代码生成的,你在里面所做的一切修改,随时可能会被丢弃。 因此在我的Flutter工程的Android编译网速优化一文中还介绍了脚本自动优化网速,以免除每次手动修改的麻烦。
创建完组件就该使用了,接下来我们一起看看如何使用组件代码。
3.3 在app中嵌入你的组件界面。3.3.1 创建组件界面首先我们创建一个简单的组件界面Galleria,将其存放在组件的gallria.dart文件中
modules/gallery/lib/gallria.dart:
import 'package:flutter/material.dart';class Galleria extends StatelessWidget { const Galleria(); @override Widget build(BuildContext context) { return Center(child: Text("Galleria")); }}复制代码
3.3.2 app中添加对组件对依赖我们的app要调用组件中的代码,需要先声明对组件的依赖:
我们可
姓名:
年龄:
电话: