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. Django学习(五)---模板扩展,开发博客页面

    (一)博客主页面开发 1.模板中可使用for循环,语法格式为: {% for xs in xxs %} HTML语句 {% endfor %} 2.更改app下的views.py, 获取后台model ...

  2. SparkMLlib-----GMM算法

    Gaussian Mixture Model(GMM)是一个很流行的聚类算法.它与K-Means的很像,但是K-Means的计算结果是算出每个数据点所属的簇,而GMM是计算出这些数据点分配到各个类别的 ...

  3. Storm笔记——技术点汇总

    目录 概况 手工搭建集群 引言 安装Python 配置文件 启动与测试 应用部署 参数配置 Storm命令 原理 Storm架构 Storm组件 Stream Grouping 守护进程容错性(Dae ...

  4. THINKPHP 3.2 PHP SFTP上传下载 代码实现方法

     一.SFTP介绍:使用SSH协议进行FTP传输的协议叫SFTP(安全文件传输)Sftp和Ftp都是文件传输协议.区别:sftp是ssh内含的协议(ssh是加密的telnet协议),  只要sshd服 ...

  5. javascript中typeof和instanceof用法的总结

    今天在看相应的javascript书籍时,遇到了typeof和instanceof的问题,一直不太懂,特地查资料总结如下: JavaScript 中 typeof 和 instanceof 常用来判断 ...

  6. cloudstack下libvirtd服务无响应问题

    在cloudstack4.5.2版本下,偶尔出现libvirtd服务无响应的情况,导致virsh命令无法使用,同时伴随cloudstack master丢失该slave主机连接的情况.最初怀疑是lib ...

  7. RobotFramework自动化测试框架的基础关键字(四)

    1.1.1        如何使用for循环 不管在哪种编程语言中,for循环都是必不可少的,在Robot Framework中,我们也可以使用for循环来做遍历处理. 我们用for循环对一个列表进行 ...

  8. 移动端touch事件封装

    <meta charset="utf-8"><meta name="viewport" content="width=device- ...

  9. echarts_部分图表配置简介_横向柱状图

    横向柱状图主要配置x位置x轴类型y轴类型(轴的类型分两种 1.category(类别)2.value(值)),代码简单(里面有注释)效果如下: var myChart = echarts.init(d ...

  10. 转载:vs2010 问题 >LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

    原文链接:http://www.cnblogs.com/newpanderking/articles/3372969.html >LINK : fatal error LNK1123: 转换到 ...