web app简介

web app其实不算是什么新鲜的东西,相比于传统的web和传统的app,web app这种web和app相结合的产物有的优点如下:

1. 开发上web app更有便捷性,ios开发一上来需要安装一堆东西,android开发也差不多,另外web app的学习成本要比平台客户端开发要低些,至少你不用去招聘ios和android程序员。只要具备基础web开发能力的人都可以比较快上手。

2. 部署方便,在很多情况下,部署一个单页web app只需要一个index.html页面文件作为容器和一个前端资源打包文件(一般叫bundle.js)即可,然后把index.html放在自己服务器项目路径下,在其中引入bundle.js,至于bundle.js则可以放在CDN上,更新web app就等于是上传并刷新CDN缓存。这样一来前端部署极其简单,基本上不需要SSH到服务器去更换文件,也可以避免自己的服务器传输比较耗费带宽的前端资源文件。

3. 单页web app如果技术选型得当,开发和维护成本都相对比较低。

4. 可以适应更多环境。

凡事都有利弊,web app也有不尽如人意的地方,web app的主要缺点如下:

1. 性能上不如原生app,这个不用多说,基本是不可改变的事实。

2. 暂时还没想到其他的。

前期准备

首先要进行技术选型,根据作者的经历,我选择的是react+flux,flux是一种数据流的架构方式,严格来说它并不是某一种特定的实现。比较常用的实现有facebook官方的flux实现,还有一些第三方实现(比如redux)。要注意的是,flux的具体实现基本不会影响到我们的项目开发,具体选择哪个实现就看你的喜好了(当然最好不要中途再做改变:D)。

那么就要来简单介绍一下react是什么,react可以说是一个改变前端生态系统的发明,传统web开发中,我们以页面为单位来设计模块,如果有多个页面都用到了某个功能,比如一个列表,那么就要重复地写HTML和JS实现它,代码抽象程度很低,冗余度很高,也不利于后期维护。react推出了UI组件的概念,让web前端开发人员可以封装UI组件用于复用。

flux这种数据流架构思想其实也不是什么新东西,但是真正在web前端大规模使用也是在开发人员使用react+flux之后的事情。flux制定了一些web前端数据获取和分发的规则,虽然刚开始看上去比较复杂,但是一旦你理解了它的思想,其实很简单,而且对于维护一个web app来说,react+flux可以说是相当不错的组合。

设计一个web app具体是在设计什么?

刚才谈到了react+flux,其实UI组件的封装和数据流的架构,它们都帮开发人员规定好了,我们需要做的就是去好好运用它,那么还有什么可设计的呢?

还是有的,而且不少。从技术角度来说,web app和ios app、android app这些原生app在技术设计上有很多共通之处:

1. 页面生命周期管理
2. 公共函数的设计
3. 局部/全局事件和通知
4. UI组件API设计
5. 常量定义
6. 网络请求
...

web app也具备一些原生app所没有或不一样的特性,例如app路由、JS(ES5/ES6差异)、使用/刷新CDN缓存、前端资源打包、快速部署等。

react+flux是怎么工作的

由于本篇文章并不是react和flux的教程,所以只会大致介绍一下它们的工作方式。

下面是官方给出的一个flux工作流程图:

详细版:

简单解释一下flux的工作流程:

在第一张图中,有两种流程:

1. Action->Dispatcher->Store->View

2. View->Action->Dispatcher->Store->View

在Action->Dispatcher->Store->View中,可以通过调用Action中的方法来执行一项操作,这个操作可以是向服务器请求数据,或仅仅在本地改变数据,操作完成后,Action会通知Dispatcher,然后由后者来分派动作和数据。在Store中,事先注册好对各个类型事件的回调函数,当Store接收到Dispatcher分发来的事件和数据时,就执行一些更新操作。另外View可以对Store注册监听器,一但Store中的数据有变化,会立即执行View预先设置好的监听器回调函数,这一般会是一个更新View的操作,这相当于一个发布-订阅模式。

在View->Action->Dispatcher->Store->View中,实际上是说指用户和View之间的交互导致数据变更(不管是请求服务器还是本地数据改变),其他操作和Action->Dispatcher->Store->View基本一样。

光看这些是十分抽象的,如果没有深入去看一个demo或者自己实现一个项目,确实有点不好理解。我将在后续介绍flux和react。

本篇中react+flux基本介绍到这。下面要谈谈具体设计。

具体设计

一个web app无非就是颠来倒去地做以下几件事:

1. 调用网络API
2. 展示页面
3. 数据本地存储(这里一般指非持久化的那种,这和原生app有所不同)
4. 接受用户输入并反馈

作为技术人员,我们首先要明确几点:

1. 明确地知道业务放需要什么。
2. 划分功能模块。
3. 弄清楚各个问题之间的依赖关系,制定模块之间的通信规范。
4. 适当考虑项目未来走向,对架构设计留有余地。
5. 分析风险。
6. 考虑如何解决依赖关系中最基础的部分,先实现基础模块(或者至少你要先对此有个大致的设计),不断在此基础上完善整个架构。这部分开发人员会花费比较大的精力去做,因为这影响到整个项目未来的几乎所有事情。同时在这个过程中不断审视架构是否合理,及时调整。
7. 单元测试,性能测试(如果项目需要且有时间的话)。

项目文件结构

好的开发习惯其中一个就是要制定清晰的项目文件结构,并且从始至终保持下去。

适当的文档描述

如果可能的话,适当写一些帮助性的架构文档,用简洁明确的词语传达你想要表达的,让后来的程序员可以快速上手。

思路和方法同一,不搞多元化

在一个项目中,对同一类事情应该有一个统一的处理方法,包括代码风格、变量和方法的命名规范、调用规范、流程规范等,事先制定出来,并且要求所有人都要遵守。

尽量少的横向依赖,尽量减少跨层访问,降低模块间耦合度

这部分内容react+flux已经帮我们做了很大一部分。

对业务方该限制的地方有明确的限制,该灵活的地方要给业务方创造灵活实现的条件

可以通过良好的设计来保证这一点。

接下来会对划分功能模块、模块间通信规范、解决依赖关系这几个方面进行说明。

功能模块的划分

在react+flux的项目中,不谈具体业务的情况下,有几个大的基础模块是一定要考虑的:

1. 展示模块
2. 网络请求模块
3. 本地存储模块
4. 路由模块
5. 公用模块

1. 展示模块

这是用户能直接看到的东西,我们用react封装各个UI组件提供出来,也可以引入第三方UI组件,这本身已经是一种进步,让我们可以在web前端“面向组件编程”,因此对UI组件的处理就尤为关键。ES6语法下,我们可以用extends react.Component来建立一个UI组件,然后在组件“类”中写初始化方法、渲染方法、生命周期函数、事件回调等方法,然后把它作为一个整体提供出去,这里就涉及到UI组件API的设计,UI组件可以接受属性值,这些属性应该尽可能的少和命名清晰、简单,保持简洁性很有必要。另外组件的展示离不开CSS和一些资源文件,作为一种封装,把CSS、图片等资源文件一并放在这个UI组件的文件夹下也是很有必要的。

2. 网络请求模块

web app网络请求全靠ajax,在和服务器交互时,应该和服务端约定好返回数据的格式,如错误代码的含义、出错信息、详细的数据格式等,并且很有必要在web app端做一层封装,比如封装出一个request模块,在服务器返回数据后首先解析返回数据,如果出错就报错,成功就执行用户回调函数等。这部分作为整个项目对外的接口应该考虑到所有可能的网络情况:服务器致命错误、普通错误、成功、超时、无网络等。

3. 本地存储模块

这部分主要交给flux处理,我们需要做的就是设计本地数据的结构,使其尽量合理并适应多种应用场景。

4.路由模块

react+flux的单页web app一般采用react-router作为路由,这可以省下你不少时间和精力,react-router是一个非常成熟和优秀的路由模块。

5. 公共模块

公共模块一般包括但不仅限于:公用函数、helper、常量定义、应用级别的功能(如展示loading框、警告框、确认框这些)。这部分功能也很重要,比如loading框,我们在发起网络请求时会展示它,数据返回时它会消失,那么这个框的出现就与上面说到的网络模块有关系,警告框和确认框也是常用的东西,这些组件都可应该在app层面上进行设计和整合,而不应该放在各个UI组件内部,因为这个是一个app中的通用功能。

模块间通信规范

在react+flux中,使用一种单向数据流的方式来分发数据,这就让整个数据走向非常清楚,我们的web app模块间通信规范就是根据这个单向数据流的思想来的。

解决依赖关系

react+flux中处理依赖关系时,用的比较多的方式无非3种:显式引入、基于事件(发布-订阅模式)、回调函数。

在要向模块中引入其他模块时(import),使用显式引入,这种依赖关系最强也最明显。如果是依赖关系没有那么强,可以考虑用后面两种,这有助于代码的简介和模块解耦。

基于事件(发布-订阅模式),举个简单的例子,flux中当Store中的数据变化时,要通知相对应的View更新页面,典型的处理方式是让Store成为一个EventEmitter,同时View对该Store addChangeListener,即成为它的订阅者,当Store改变时会自动调用该View的监听回调,让View更新界面。

基于回调函数,有一个非常典型的用例,在设计通用的警告框和确认框组件时,有时我们需要在用户点击“确定”和“取消”按钮时做一些事情,当然也可能什么也不做。这时候我们不要忘了JS中函数是一等公民这件事,我们可以把事件处理函数传递给警告框和确认框组件,这样就很巧妙的解决了跨组件、跨模块通信而不会使模块过于耦合了。

如何设计和实现一个web app的更多相关文章

  1. 在2015年 开发一个 Web App 必须了解的那些事

    在过去的一年里,我在从头开始开发我的第一个重要的Web应用.经验教会了很多以前不知道的东西,特别是在安全性和用户体验方面. 值得一提的是,我上一次尝试构建的任何合理复杂性是在2005年.所以,在安全防 ...

  2. 开发一个 Web App 必须了解的那些事

    在过去的一年里,我在从头开始开发我的第一个重要的Web应用.经验教会了很多以前不知道的东西,特别是在安全性和用户体验方面. 值得一提的是,我上一次尝试构建的任何合理复杂性是在2005年.所以,在安全防 ...

  3. Anaconda+django写出第一个web app(一)

    在安装好Anaconda和django之后,我们就可以开始创建自己的第一个Web app,那么首先创建一个空文件夹,之后创建的文件都在这个文件夹内. 启动命令行进入此文件夹内,可以先通过如下命令查看一 ...

  4. Anaconda+django写出第一个web app(十一)

    今天我们来学习给页面添加一个Sidebar,根据Sidebar跳转到相应的tutorial. 打开views.py,编辑single_slug函数: def single_slug(request, ...

  5. Anaconda+django写出第一个web app(十)

    今天继续学习外键的使用. 当我们有了category.series和很多tutorials时,我们查看某个tutorial,可能需要这样的路径http://127.0.0.1:8000/categor ...

  6. Anaconda+django写出第一个web app(五)

    今天开始学习网页风格和设计,就像python有Web框架一样,也有一些CSS框架.对于CSS框架,我们可以使用默认的样式,也可以在原基础上编辑修改.本教程使用的是materialize这个CSS框架[ ...

  7. Anaconda+django写出第一个web app(四)

    前面对Models有了一些了解,今天开始进一步了解Views,了解Views如何和Models交互以及了解模板(templates). 打开main文件夹下的views.py,重新编写homepage ...

  8. Anaconda+django写出第一个web app(三)

    前面我们已经建立了模型Tutorial,也已经可以用Navicat Premium打开数据看查看数据,接下来我们通过建立admin账户来上传数据. 在命令行执行如下命令来创建用户: python ma ...

  9. Anaconda+django写出第一个web app(二)

    今天开始建立App中的第一个Model,命名为Tutorial. Model的定义在main文件夹下的models.py中通过类进行,我们希望Tutorial这个model包含三个属性:标题.内容和发 ...

随机推荐

  1. iOS 模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.

    引导 Copyright © PBwaterln Unauthorized shall not be *copy reprinted* . 对于从事 iOS 开发人员来说,所有的人都会答出「runti ...

  2. 动态语言的灵活性是把双刃剑 -- 以Python语言为例

    本文有些零碎,总题来说,包括两个问题:(1)可变对象(最常见的是list dict)被意外修改的问题,(2)对参数(parameter)的检查问题.这两个问题,本质都是因为动态语言(动态类型语言)的特 ...

  3. monkeyscript - 定制化monkey流程

    作为移动端测试必须掌握的初级Android稳定性工具:monkey,提到它时,脑海里一般涌现出两句话: 1.我会用,很简单 就是一行命令,一回车就开始跑起来了 2.使用问题多,不好用 太随机,很多操作 ...

  4. (转) Spring Boot MyBatis 连接数据库

    最近比较忙,没来得及抽时间把MyBatis的集成发出来,其实mybatis官网在2015年11月底就已经发布了对SpringBoot集成的Release版本,Github上有代码:https://gi ...

  5. HDOJ2001-两点坐标的距离

    Problem Description 输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离.   Input 输入数据有多组,每组占一行,由4个实数组成,分别表示x1,y1,x2,y2 ...

  6. Ubuntu中使用iptables

    (一) 设置开机启动iptables # sysv-rc-conf --level 2345 iptables on (二) iptables的基本命令 1. 列出当前iptables的策略和规则 # ...

  7. webpack2 项目

    webpack2 项目   实例gif图: 目录截图: 目录介绍: dist目录(最后生成的目录,里面文件为配置webpack自动生成的): c/:css文件夹; i/:img文件夹; j/:js文件 ...

  8. bzoj 3594: [Scoi2014]方伯伯的玉米田

    3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec  Memory Limit: 128 MB Submit: 1399  Solved: 627 [Submit][ ...

  9. Nlpir Parser智能语义分析系统文本新算法

    文本挖掘或者文档挖掘是一个从非结构化文本信息中获取用户感兴趣或者有用的模式的过程文本挖掘涵盖多种技术,包括信息抽取,信息检索,自然语言处理和数据挖掘技术.它的主要用途是从原本未经使用的文本中提取出未知 ...

  10. Fliptile 翻格子游戏[Usaco2007 Open]

    题目描述 Farmer John knows that an intellectually satisfied cow is a happy cow who will give more milk. ...