APP软件版本控制设计

[个人理解]软件版本是随着项目的不断研发,在不同阶段产生的一个重要里程碑记录。针对不同的阶段,存在软件功能的更新或软件问题的修复而出现的一种软件设计模式。

为什么会存在不同的APP软件版本

  1. 业务不断的迭代更新。

一个好的产品总是在不断的迭代开发、不断的增加一些新的功能。我们在软件发布新功能时, 要尽可能的让用户被动的知道软件功能进行了更新
,这时候就需要我们将新的软件功能告知用户,让用户去使用新功能。
例如,我们第一次APP只发布了一个文章阅读的功能,后来我们在APP上增加了一个视频播放的功能。这时候需要用户进行更新APP才可以查看,但是存在部分用户不愿意更新到最新版本,我们要做到新版本的发布不影响旧版本的使用。保证多个版本同时能够使用。
2.现有软件版本的bug。
在当前我们发布的APP软件中,如果我们发现了软件存在的bug,此时需要修复bug,重新发布版本,就需要用户在使用时强制更新到最新的版本。

APP软件版本与Web网页版本之间的区别

1.APP是使用实在用户的移动设备上进行的,我们运行的代码也是在用户的移动设备上。服务器端是无法让用户每次进来都是加载最新的软件功能。
2.Web网页是运行在浏览器中,用户使用是通过一个网页地址(网页链接),服务器端是可以保证用户每次让问链接都是加载的最新功能。
3.因此APP软件版本的更新,需要用户主动的去下载最新的APP软件。每次下载的APP软件都是一个新的版本。
4.在APP端软件更新之后,我们不能强制的让用户必须更新,要做到更新后可以使用,同时未更新的版本也能正常使用,这就需要我们针对不同的版本进行不同的处理。

APP软件版本流程图


通过上图,我们将用户使用的设备成为客户端。每个用户手中的软件版本存在不同的情况,我们要让用户无感知的情况下,针对不同的用户的不同版本请求不同的数据。
例如,上图安卓设备用户,用户1使用的APP版本是版本2,用户2使用的版本比用户1的版本要低一些,使用的是版本1,用户3使用的是版本3,为最新的APP软件。虽然我们APP软件的最新版本是版本3,但我们要做到每个用户使用的软件版本都能正常使用。

APP软件版本控制实现原理分析


1.这里的客户端1、客户端2和客户端3分别对应上图的用户1、用户2和用户3。
2.客户端1使用的是版本2,在请求服务端时,服务端根据当前请求地址中的参数,来判断用户当前的版本号,根据不同的版本好转发到后端不同的接口地址。其他的客户端同理进行。
3.当我们软件设置了强制更新,每当用户操作APP时,都会检测软件当前的版本与最新的版本,如果发现不一致则会提醒用户进行更新,如不更新则无法使用。

APP软件版本更新的模式

1.强制更新
强制更新指的是,用户使用的版本与当前最新版本不一致,则会提示用户更新否则无法使用。一般不推荐使用强制更新,如发现旧版本存在重大bug时,才强制用户进行强制更新。
2.多版本兼容
多版本兼容指的是,不管APP更新了多少个版本并且用户使用的是某一个版本,都能正常操作。对用户的体验性更好。

APP软件版本控制需要考虑些什么

1.数据库设计
数据库中我们需要考虑到不同的用户设备,不同的版本号等信息。

字段 类型 描述 示例值
id int(10) 主键 1
device_type varchar(32) 设备类型 Android
device_model varchar(32) 设备机型 vivo x6
in_version varchar(32) 内部版本号 v1.0.1
out_version varchar(32) 外部版本号 v1.0.1
version_url varchar(255) 更新包地址 https://www.xxx.com/v1
is_force tinyint(10) 是否强更 1
update_msg varchar(32) 更新提示信息 增加视频播放功能
is_latest tyintint(10) 是否为最新版本 1

2.监控内容
一般的软件设计都会针对APP使用情况进行检测,比如设备类型、使用时间、启动次数、浏览时间等情况进行检测,后台做一些数据分析使用。

字段 类型 描述 示例值
id int(10) 主键 1
device_type varchar(32) 设备类型 Android
device_model varchar(32) 设备机型 vivo x6
version varchar(32) 版本号 v1.0.1
open_time datetime(0) 启动时间 2019-02-02 12:09:09
3.代码设计

代码一般是通过分层设计,降低代码的耦合度、同时也能提高代码的扩展性。如上图,我们所有的业务逻辑一般都是在controller层进行处理,我们v1版本请求controller下面v1,v2版本请求controller下面v2,同理后面的版本也按照这种模式进行处理。针对一些不需要版本控制的逻辑则单独设置为公共的控制器进行处理。
4.路由地址
上面代码设计中,我们将不同的版本分为不同的模块,路由地址主要是为了区分不同的版本请求不同的模块。v1的路由地址则请求v1控制器,v2的路由地址则请求v2控制器。

APP软件版本具体实现

这里使用PHP中的ThinkPHP5.1进行部分代码演示
1.数据库设计

// 数据库直接根据上面表的结构进行设计,创建一些模拟数据。

2.路由定义

use think\facde\Route;

// 新闻列表路由地址
Route::get('news/list/:ver', 'index/:ver.News/list');
// 文章列表路由地址
Route::get('article/list/:ver', 'index/:ver.Article/list');

上面的:ver是一个url必填变量,客户端APP在请求服务端时,请求的url中携带着该变量,我们根据定义好的路由就会自动的转发到对应版本下面的控制器中。如下url示例格式:

// 请求版本1中的新闻接口
https://www.xxx.com/news/list/v1
// 请求版本2中的新闻接口
https://www.xxx.com/news/list/v2

3.业务控制器

// v1版本的新闻接口
namespace app\index\v1\News;

class News 
{
    public function list()
    {
        // 这里返回v1版本的数据格式
    }
}

// v2版本的新闻接口
namespace app\index\v2\News;

class News 
{
    public function list()
    {
        // 这里返回v2版本的数据格式
    }
}

当我们部分接口存在小变动,也可以不用单独增加一个版本接口,只需要在原来的版本上增加我们需要的字段接口,如下示例数据格式。

// v1版本,新闻模块返回的数据格式
[
    'id' => 1,
    'title' => 'APP软件版本控制',
    'created_at' => '2019-02-12'
];
// v2版本,新闻模块返回的数据格式
[
    'id' => 1,
    'title' => 'APP软件版本控制',
    'created_at' => '2019-02-12',
    'author' => '卡二条'
];