作为前端程序员,我们经常会遇到这样的场景,例如
进入一个营销活动页面,会根据后端下发的不同 type
,前端页面展示不同的弹窗。
- async getMainData() {
- try {
- const res = await activityQuery(); // 请求后端数据
- this.styleType = res.styleType;
- if (this.styleType === STYLE_TYPE.Reward) {
- this.openMoneyPop();
- }else if (this.styleType === STYLE_TYPE.Waitreward) {
- this.openShareMoneyPop();
- } else if (this.styleType === STYLE_TYPE.Poster) {
- this.openPosterPop();
- } else if (this.styleType === STYLE_TYPE.Activity) {
- this.openActivityPop();
- } else if (this.styleType === STYLE_TYPE.Balance) {
- this.openBalancePop();
- } else if (this?.styleType === STYLE_TYPE.Cash) {
- this.openCashBalancePop();
- }
- } catch (error) {
- log.error(MODULENAME, '主接口异常', JSON.stringify(error));
- }
- }
我们在写的时候也许不觉得,但是当我们去维护别人的代码时,这个代码的话看了就想打人,未来新增一种弹窗类型的话,我们需要到 getMainData
内部去补一个 else if
,一不小心可能就会影响到原有的逻辑,并且随着迭代函数会越来越大。但其实每种弹窗是相互独立的,我们并不关心其他弹窗的逻辑。
此时,就需要策略模式了。
1.定义:策略模式作为一种软件设计模式 (opens new window),指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。
策略模式:
- 定义了一族算法(业务规则);
- 封装了每个算法;
- 这族的算法可互换代替(interchangeable)
2.运用:借助策略模式的思想,我们可以尝试这样写:
- const strategies = {
- FirstStrategy() {
- console.log("Called FirstStrategy");
- },
- SecondStrategy() {
- console.log("Called SecondStrategy");
- },
- ThirdStrategy() {
- console.log("Called ThirdStrategy");
- }
- }
-
- const execute = (strategy) => {
- return strategies[strategy]();
- }
-
- execute('FirstStrategy')
- execute('SecondStrategy')
- execute('ThirdStrategy')
将不同的处理逻辑都放到strategies这个对象里面去统一维护,然后通过给execute()这个方法传递不同的strategy参数,然后通过统一的strategies[strategy]()去根据参数匹配不同的处理逻辑。
当我们要处理的情况较多时,如果将所有的代码都写到一个文件中,看上去还是会有些臃肿,这个时候我们就要考虑是否可以将业务代码与逻辑处理代码分离开来,于是就有了进一步的优化,如下:
1.我们可以将不同类型的处理逻辑代码全都拿到一个单独的文件当中,然后给出一个统一的函数去供业务使用:
- const popTypes = {
- [STYLE_TYPE.Reward]: function() {
- ...
- },
- [STYLE_TYPE.Waitreward]: function() {
- ...
- },
- [STYLE_TYPE.Poster]: function() {
- ...
- },
- [STYLE_TYPE.Activity]: function() {
- ...
- },
- [STYLE_TYPE.Balance]: function() {
- ...
- },
- [STYLE_TYPE.Cash]: function() {
- ...
- },
- }
-
- export function openPop(type){
- return popTypes[type]();
- }
2.在我们需要的文件当中引入上面的配置文件
import { openPop } from './popTypes';
3.在拿到不同参数时再去根据参数,调用方法
- async getMainData() {
- try {
- const res = await activityQuery(); // 请求后端数据
- openPop(res.styleType)
- } catch (error) {
- log.error(MODULENAME, '主接口异常', JSON.stringify(error));
- }
- }
现在,我们的代码是不是看上去就非常的清晰了呢?嘿嘿~~