首页>>前端>>JavaScript->【JavaScript设计模式】状态模式重构文件切片上传

【JavaScript设计模式】状态模式重构文件切片上传

时间:2023-12-01 本站 点击:0

一、什么是状态模式?

状态模式的定义:

对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。 状态模式的优点:

结构清晰,状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。

将状态转换显示化,减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。

状态类职责明确,有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。 状态模式的缺点:

状态模式的使用必然会增加系统的类与对象的个数。

状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。

状态模式对开闭原则的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源码,否则无法切换到新增状态,而且修改某个状态类的行为也需要修改对应类的源码。 状态模式的应用场景:

当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以考虑使用状态模式。

一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时。

二、文件切片上传

文件切片上传是一个比较常见的需求。其主要步骤如下:

读取文件基本信息

将文件按照指定大小切片

创建上传记录,用以标识文件片段

依次、并行上传文件片段(需注意浏览器的最大并行请求数) 另外还涉及到删除、重新上传等功能。 在文件上传的不同阶段,对文件不同操作的处理逻辑是不一样的,会用到大量if-else语句。 我们先看一段关于删除文件的代码:

Upload.delete = function() {  if (/* 创建上传记录中 */) {    /* 取消创建上传记录 */    /* 删除本条数据 */  } else if (/* 创建上传记录成功 */) {    /* 删除上传记录 */    /* 删除本条数据 */  } else if (/* 创建上传记录失败 */) {    /* 删除本条数据 */  } else if (/* 文件上传中 */) {    /* 删除上传记录 */    /* 取消上传 */    /* 删除本条数据 */  } else if (/* 文件上传失败 */) {    /* 删除上传记录 */    /* 删除本条数据 */  } else if (/* 文件上传成功 */) {    /* 删除上传记录 */    /* 删除文件 */    /* 删除本条数据 */  }}

如果后续需求调整,比如新增/*文件暂停上传*/的场景,需要改写else-if逻辑,这会使得我们的代码变得越来越庞大,从而变得难以维护和阅读。而且,在实际开发中,需要处理的逻辑肯定比这多得多,因此,重构此类代码是非常有必要的。

三、重构以上代码

1、我们先为文件上传的每个阶段都定义一个状态类:

/* 创建上传记录中 */let CreatingState = function () { }/* 创建上传记录成功 */let CreateSucceedState = function () { }/* 创建上传记录失败 */let CreateFailState = function () { }/* 文件上传中 */let UploadingState = function () { }/* 文件上传成功 */let UploadSucceedState = function () { }/* 文件上传失败 */let UploadErrorState = function () { }

2、分别为每个状态类设置删除方法

/* 创建上传记录中 */CreatingState.prototype.delete = function () {    /* 取消创建上传记录 */    /* 删除本条数据 */}/* 创建上传记录成功 */CreatingState.prototype.delete = function () {    /* 删除上传记录 */    /* 删除本条数据 */}/* 创建上传记录失败 */CreatingState.prototype.delete = function () {   /* 删除本条数据 */}/* 文件上传中 */CreatingState.prototype.delete = function () {    /* 删除上传记录 */    /* 取消上传 */    /* 删除本条数据 */}/* 文件上传成功 */CreatingState.prototype.delete = function () {    /* 删除上传记录 */    /* 删除本条数据 */}/* 文件上传失败 */CreatingState.prototype.delete = function () {    /* 删除上传记录 */    /* 删除文件 */    /* 删除本条数据 */}

3、创建Upload构造函数,为每种状态类创建一个示例对象

let Upload = function () {  this.creatingState = new CreatingState(this);  this.createSucceedState = new CreateSucceedState(this);  this.createFailState = new CreateFailState(this);  this.uploadingState = new UploadingState(this);  this.uploadSucceedState = new UploadSucceedState(this);  this.uploadErrorState = new UploadErrorState(this);  this.deleteSucceedState = new DeleteSucceedState(this)}

4、在不同的上传阶段变更Upload的状态,也是为了将事件委托给对应的状态类来执行

/* 创建上传记录中 */this.uploadState = this.creatingState/* 创建上传记录成功 */this.uploadState = this.createSucceedState/* 创建上传记录失败 */this.uploadState = this.createFailState/* 文件上传中 */this.uploadState = this.uploadingState/* 文件上传成功 */this.uploadState = this.uploadSucceedState/* 文件上传失败 */this.uploadState = this.uploadErrorState/* 将删除事件委托给当前状态类 */Upload.prototype.delete = function () {  this.uploadState.delete()}

5、使用

let uploader = new Upload();/* 删除文件 */uploader.delete()

重构结束。

原文:https://juejin.cn/post/7096410361313624071


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/JavaScript/6378.html