使用策略模式封装拦截器

通过if-else 来实现拦截器的封装

axios.interceptors.response.use((res) => {
  let {message, statusCode} = res.data.data
  //  退出登录状态码
  let logoutCodes = new Set([435001, 435011, 436050])
  if (statusCode === 1000) {
    //  更新全局token
    let {pragma} = res.headers
    if (pragma) window.token = pragma
    //  返回数据
    return res.data.data

  } else if (logoutCodes.has(statusCode)) {
    setTimeout(() => window.logout(), 1000)
    return Promise.reject({message})
  } else {
    return Promise.reject({message,statusCode})
  }
}, (error) => {
  return Promise.reject(error.response.data)
})

首先,说一下上面拦截器封装的逻辑,当状态码为1000的时候,请求数据成功,当状态码为435001, 435011, 436050的时候,退出登录。其他状态码的时候,返回错误信息。 在最开始封装拦截器的时候,使用了大量的if-else的。在可读性上是不太 友好的,而且,后期的维护也不是很友好。 最近,正好在学习设计模式,感觉这个可以通过策略模式来进行优化.

策略模式就是将一系列的算法单独封装起来,并且他们可以相互替换。策略模式有两个类:一是策略类,二是环境类。策略类封装了具体的算法,并负责具体的计算过程。环境类是接收客户端的请求,随后把请求委托给某一个策略类。

第一次使用策略模式进行的封装

// 定义策略类
let Policy = {
  // 状态码满足1000的情况下
  success: function(res) {
    let {pragma} = res.headers;
    pragma && (window.token = pragma);
    //  返回数据
    return res.data.result
  },
  // 状态码满足435001,435011, 436050情况下,登出
  logout: function(res) {
    let {message} = res.data;
    setTimeout(() => window.logout(), 1000)
    return Promise.reject({message})
  },
  // 状态码满足其他情况下
  other: function() {
    let {message, statusCode} = res.data
    return Promise.reject({message,statusCode})
  }
}
/**
 * 响应拦截器
 * @author liuqiuyue
 * @date 2019-04-29
 */
axios.interceptors.response.use((res) => {
  let {statusCode} = res.data
  //  退出登录状态码
  let logoutCodes = new Set([435001, 435011, 436050])
  let codeBol = (statusCode === 1000);
  let logoutBol = (logoutCodes.has(statusCode));
  // 满足状态码为1000的时候,执行的方法
  codeBol && Policy.success(res);
  // 状态码满足435001,435011, 436050情况下,登出
  !codeBol && logoutBol && Policy.logout(res);
  // 状态码满足其他情况下
  !codeBol && !logoutBol && Policy.other(res);
}, (error) => {
  return Promise.reject(error.response.data)
})

封装了一个对象,这个对象里面含有不同的方法,在满足条件的时候,去走不同策略类中的方法。看似是策略模式,我也一直这么认为,这是符合策略模式的。之前也经常认为中写法是符合策略模式的。经高人指点之后,发现,这其实不算一个真正的策略模式,可以说是一个伪策略模式。为什么这么说呢? 推荐阅读 https://www.runoob.com/?s=%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8

上面的代码 中Policy是对一系列的算法进行了封装,但是会发现,其实是没有环境类的,只是通过不同的条件,去调取不同的方法的。所以,他是伪策略模式。

对策略模式进行二次封装 通过一个加减乘除的算法的案例来解释

策略类

function computed() {

}
computed.prototype.add = function(a, b) {
    console.log(‘走了嘛‘)
    return a+b
}
computed.prototype.subtraction = function(a, b) {
    return a-b
}
computed.prototype.Multiply = function(a,b) {
    return a*b
}
computed.prototype.except = function(a, b) {
    return a/b
}

环境类

// 定义了环境类
function context() {

}
context.prototype.init= function(a, b) {
    this.a =a;
    this.b = b;
    console.log(‘数值初始化‘, this.a, this.b)
}
context.prototype.getWay = function(way) {
    console.log(‘way‘, way)
    return way(this.a, this.b)

}

客户端的请求,具体的实现

var c = new context()
c.init(10, 20)
let com = new computed();
c.getWay(com.add)
console.log(‘结果‘, c.getWay(com.add))

在解释这种说法之前,先说一下面向对象的概念,

(1)类,有相同的特征和行为的事物的抽象,

( 2)对象 :类的一个实例。

那么。js是面向对象语言嘛?

准确点说,js是一种基于面向对象的语言,因为,她没有提供抽象,继承,重载等有关面向对象语言的许多功能,而是把其他语言所创建的复杂对象统一起来,从而形成一个非常强大的对象系统,这种独特性称它为prototype_basedOO(基于原型的面向对象)。传统的是class-basedOO(基于类的面向对象)

上面的这种写法就是使用的js的基于原型的面向对象去实现的策略模式。

下面,通过传统的基于类的面向对象思想进行封装

Strategy抽象类

export class Strategy {
    // 抽象类
    constructor() {

    }
    init(num1, num2) {
        console.log(‘抽象类‘, num1, num2)
        this.num1 = num1;
        this.num2 =num2;
    }
}

Add方法,继承于Strategy类

import  {Strategy} from  ‘../js/Strategy‘
export class Add extends Strategy{
    constructor(num1, num2) {
        super(num1, num2)
    }
    init(num1, num2) {
        console.log(‘数据‘, num1, num2)
        return num1+num2
    }
}

Context环境类

// 环境类
let {Strategy} = require(‘../js/Strategy‘)
let strategy = new Strategy()
export  class Context {
    constructor() {
        this.strategy =strategy
    }
    // 定义抽象类的方式
    initWay(way) {
        // 数据的初始化
        this.strategy = way
        console.log(‘数据的初始化‘,  this.strategy)
    }
    // 计算
    getWay(num1, num2) {
        console.log(‘获取对应的方法‘,  num1, num2)
        console.log(‘结果‘, this.strategy.init(num1, num2))
        return this.strategy.init(num1, num2)
    }
}

实现

var contenx = new Context()
context.getWay(add)

原文地址:https://www.cnblogs.com/mn6364/p/11070040.html

时间: 2024-08-01 00:00:06

使用策略模式封装拦截器的相关文章

【设计模式】策略模式 —— 封装行为的大局观

OO基础 抽象 封装 多态 继承 OO原则 封装变化 多用组合,少用继承 针对接口编程,不针对实现编程 OO模式 策略模式——定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 1. 知道OO基础,并不足以让你设计出良好的OO系统. 2. 良好的OO设计必须具有可复用.可扩充.可维护三个特性. 3. 模式可以让我们建造出具有良好OO设计质量的系统. 4. 模式被认为是历经验证的OO设计经验. 5. 模式不是代码,而是针对设计问题的通用解决方案.你可以把它们

struts2第四天——拦截器和标签库

一.拦截器(interceptor)概述 struts2是个框架,里面封装了很多功能,封装的很多功能都是在拦截器里面. (属性封装.模型驱动等都是封装在拦截器里面) struts2里面封装了很多功能,有很多拦截器,每次执行一部分拦截器,比如一些默认拦截器等 默认拦截器的位置在 core的jar包的struts-default.xml里边<interceptor>标签里边 二.拦截器基本原理 拦截器在什么时候执行: 在action对象创建之后和action方法执行之前进行执行(使用在相关位置打断

Struts2(XWork)拦截器的功能介绍:

  拦截器 名字 说明 Alias Interceptor alias 在不同请求之间将请求参数在不同名字件转换,请求内容不变 Chaining Interceptor chain 让前一个Action的属性可以被后一个Action访问,现在和chain类型的result(<result type="chain">)结合使用. Checkbox Interceptor checkbox 添加了checkbox自动处理代码,将没有选中的checkbox的内容设定为false,

【设计模式】 模式PK:策略模式VS状态模式

1.概述 行为类设计模式中,状态模式和策略模式是亲兄弟,两者非常相似,我们先看看两者的通用类图,把两者放在一起比较一下. 策略模式(左)和状态模式(右)的通用类图. 两个类图非常相似,都是通过Context类封装一个具体的行为,都提供了一个封装的方法,是高扩展性的设计模式.但根据两者的定义,我们发现两者的区别还是很明显的:策略模式封装的是不同的算法,算法之间没有交互,以达到算法可以自由切换的目的:而状态模式封装的是不同的状态,以达到状态切换行为随之发生改变的目的.这两种模式虽然都有变换的行为,但

【LabVIEW技巧】策略模式

前言 在之前的文章中,我们提到了如何学习OOP以及对应的简单工厂模式,由于时间比较长,我们先回顾一下之前讲到的一些内容,然后继续了解策略模式. 为什么学习OOP 在测控系统的软件开发过程中,我们LabVIEW工程师一直认为程序完成功能就可以了,但是随着程序的越来越复杂,我们发现很多情况下成型系统到后期无法添加功能或很难添加功能. 是什么阻碍了我们软件系统的开发?为什么在需求沟通不明确的前期,我们无法开发软件:在需求明确的后期,又无法对软件进行灵活修改. 如果大家仔细分析中国的四大发明,就会发现活

第二章 策略模式

策略模式封装了变化. 标准策略模式: /** * Created by hero on 16-3-29. */ public abstract class CashSuper { public abstract double acceptCash(double money); } /** * Created by hero on 16-3-29. */ public class CashNormal extends CashSuper{ @Override public double accep

02—策略模式

描述:是用来封装算法的,但在实践中,我们发现可以用来封装任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性. 简单说就是“策略模式封装了变化”. 实例:用一个超市促销活动收银的小例了来讲解一下,比如双11了,我们的超市要举行促销活动,活动类型分类:正常收费.满300返100.打8折三种. 那我们先分析一下,三种收费方式,每种的计算方式都不同,有很多种实现方式,我们先用简单工厂实现,然后在用策略模式实现,好下面我们先用简单工厂实现一下:

第八章 拦截器机制——《跟我学Shiro》

8.1 拦截器介绍 Shiro使用了与Servlet一样的Filter接口进行扩展:所以如果对Filter不熟悉可以参考<Servlet3.1规范>http://www.iteye.com/blogs/subjects/Servlet-3-1了解Filter的工作原理.首先下图是Shiro拦截器的基础类图: 1.NameableFilter NameableFilter给Filter起个名字,如果没有设置默认就是FilterName:还记得之前的如authc吗?当我们组装拦截器链时会根据这个名

设计模式之策略模式20170720

行为型设计模式之策略模式: 一.含义 策略模式是一种比较简单的模式,也叫做政策模式,其定义如下: 定义一组算法(可抽象出接口),将每个算法都封装起来,并且使它们之间可以互换(定义一个类实现封装与算法切换) 二.代码说明 1.主要有两个角色 1)Context封装角色 它也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略,算法的直接访问,封装可能存在的变化. 2)策略角色 该类含有具体的算法 2.在用C实现过程中也是参考这种思想,以压缩,解压算法举例,具体实现如下: 1)策略模式使用场景