首先,如何开始一个项目?
在一个项目开始前,一般会得到一个需求文档,一个设计文档,知道项目用户,项目的目标,项目截止日期等信息。当拥有了这些信息后,就需要做一些关键决策了,如何部署,采用单页面应用还是多页面应用,是否需要服务端渲染,使用哪个框架,React/Vue/Angular等,使用哪种架构模式。
然后,需要考虑一个核心问题,项目的可扩展性。项目后续可能会如何发展。
在一般的工作流程中,很多人在面对一个新项目时,几乎是下意识的根据公式技术栈,使用脚手架工具,直接创建一个新项目,并进入开发,并没有项目架构,只是根据经验进行需求开发。
那为什么需要架构呢?
在解释这个问题之前,需要明确 React/Vue/Angular 这些现在前端开发框架都是负责组件渲染、局部状态管理、用户交互和用户界面生命周期,但是它们不提供构建完整应用所需的所有内容。例如:数据转换的模式、身份验证、日志记录等。
但在实际开发中,框架负责的组件所负责的工作早已超出了UI渲染这个范围,经常会把业务逻辑放在组件中,比如:API调用,执行业务规则。随着应用程序的增长,这会使维护变得更加困难。如果需要进行业务逻辑的测试,在执行测试用例时也需要挂载组件,需要一个完整的React环境。如果需要切换框架,那么在业务逻辑和组件耦合的情况下,需要重写所有逻辑。
什么样的架构才是理想的架构?
- 可以在没有用户界面组件的情况下进行业务逻辑测试
- 可以随意替换框架,并且不用重写业务逻辑
- 新加入的开发者可以快速理解代码并开始执行开发任务
- 数据源改变不会影响业务逻辑
- 添加新的功能不会影响现有的功能
- 不同的团队可以在不同的层和模块上独立工作
- 工具选择根据团队需求决定,不会因为架构强制要求使用特定工具
如何尽量靠拢理想架构?
要做到以上几点,需要团队的技术自律。
- 业务逻辑应该存在于框架无关的模型里,只有使用TyprScript或者JavaScript实现的纯逻辑
- 要根据实际的复杂度进行工具选择而不是盲目跟随社区推荐
- 数据访问和业务逻辑隔离
- 业务逻辑在任何框架中都一样适用
- 视图层只负责展示,组件要保持简洁,它们只负责接收数据,展示数据,获取用户输入,并将这些输入传递给下一个环节
- CLI test:要做到可以在不重复逻辑的情况下更换用户界面
架构模型
在逻辑上,可以把前端项目分为3层。视图层、逻辑层、数据层。
视图层负责UI组件的处理,这一层用于显示信息并捕捉用户的交互。这一层没有业务逻辑和API调用,纯粹用于展示。
逻辑层负责管理业务逻辑和规则。这一层负责验证业务逻辑和协调操作。
数据层负责管理API的集成。同时也负责外部数据源的状态管理。这一层会获取数据并对其进行转换并进行缓存。
这样分层的好处是,缩小了每一层关注点,在每一层只需关注一个问题,测试独立,每一层可以单独测试。让代码库更容易维护。
这里有一个重要的概念,这些分层不是物理分层而是逻辑分层。它们可以分布在不同的设备上。可以视图层在浏览器中,逻辑层和数据层在服务器上,也可以都在浏览器中部署。这需要根据业务需求灵活调整。
对于前端应用逻辑层和数据层是可选的,应该在需要它们解决实际问题时再加上,而不是为了分层而分层,比如一个静态网站,逻辑层和数据层明显就是不需要的。
同时在一个团队中,一致性是非常重要的,一致性让代码库变得更可预测,团队间沟通更清晰。
架构扩展
扩展方式主要有两种:垂直扩展和水平扩展
这两个术语来自后端开发,在需要扩展时,后端可以通过增加更多服务器来实现水平扩展,或者在一个服务器上增加CPU或者内存来实现垂直扩展。是物理层面的扩展。
在前端场景,无法在用户的设备上增加更多的CPU或内存。这里主要指架构的可扩展性,是逻辑层面的扩展。如果代码库可以很容易的增加功能,那么说明代码库的可扩展性就很好。
垂直扩展指增加更多的层次,让层次更深,在以上三个层次中再细分层次。
水平扩展就是增加更多的切片,增加宽度。根据功能进行区分。
垂直扩展和水平扩展可以同时使用,在多数情况下,水平扩展更有价值,因为它可以实现并行开发,这在团队开发中尤其重要。
这样的方式在一定程度上让代码库向高内聚和低耦合靠拢。