JSSDK设计探索

作者: 陈道乐 | 来源:发表于2020-03-07 00:15 被阅读0次

    工程结构

    ├── build
    │   ├── outputs // 最终打包文件
    │   └── temp    // 暂存目录主要用于处理 es6 翻译后的文件
    ├── demo
    │   └── index.html   // 测试用的Demo
    ├── gulpfile.js
    ├── lib
    │   ├── api
    │   │   └── AnalyticsApi.js  // SDK对外接口
    │   ├── control   // 包含基础的流程操作
    │   │   ├── AnalyContext.js
    │   │   └── InitializeHelper.js 
    │   ├── model     // 上报的数据结构
    │   │   ├── AnalyEvent.js
    │   │   ├── PageInfo.js
    │   │   └── UserInfo.js
    │   ├── request   // 包含所有的请求操作
    │   │   ├── AnalyRequestRunnable.js
    │   │   ├── AsyncPool.js
    │   │   ├── DebugRequestRunnable.js
    │   │   └── SinglePool.js
    │   └── support   // 工具方法
    │       ├── AlBase64.js
    │       ├── AlConsole.js
    │       ├── AlCookie.js
    │       ├── AlDevice.js
    │       ├── AlMd5.js
    │       ├── AlType.js
    │       └── pool
    │           ├── AlPool.js
    │           ├── AlPoolRunnable.js
    │           └── Serializable.js
    └── package.json
    

    项目解析

    1. api

    包含所有的对外接口,基本原则如下

    • 不包含任何逻辑代码
    • 简约明了
    import AnalyContext from "../control/AnalyContext"
    
    class Facade {
    
        initialize(opts) {
            AnalyContext.getInstance().initialize(opts);
        }
        ....
    }
    
    //包含一个这个方法,是无奈之举,防止被外部代码bind
    function buildMethods() {
        const facade = new Facade();
        return {
            initialize: facade.initialize.bind(facade),
            login: facade.login.bind(facade),
            logout: facade.logout.bind(facade),
            track: facade.track.bind(facade),
            trackSinglePage: facade.trackSinglePage.bind(facade)
        }
    }
    
    window.webAanlytics2020 = buildMethods();
    

    control

    包含初始化时的配置动作,比如配置参数校验,初始化监听动作

    
    class AnalyContext  {
        
        // 持有整个应用期间需要长期使用的model
        constructor() {
            this.userInfo = new UserInfo();
            this.pageInfo = new PageInfo();
        }
        
        initialize(opts) {
        
            // 形式如下InitializeHelper帮助解析参数,后续代码开始配置
            // 缺陷:逻辑部分应该放在, InitializeHelper中处理,但是代码不多,权衡下,放在AnalyContext容易改动
            this.initializeHelper = new InitializeHelper();
            this.initializeHelper.initialize(opts);
    
            //debug 配置
            if (this.initializeHelper.showLogEnable()) {
                AlConsole.debug(true);
            }
    
            .....
        }
    
    }
    

    model

    这个层就更加简单了,全都是数据结构

    class AnalyEvent {
        constructor() {
            this.event = "";
            this.properties = {};
            this.env = {}
        }
        
        .....
    }
    
    class UserInfo {
        ....
    }
    
    class PageInfo {
        ....
    }
    

    request

    用于处理异步批量发送 或者 立即发送模式(Single Mode), 次部分的设计使用的是support目录下的pool功能,设计如下:

    request 具体实现
    // 只包含一个run方法,支持序列话操作,用于支持日志本地存储
    class AlPoolRunnable extends Serializable {
        run() {};
    }
    
    
    // 该类是SingleMode模式和BatchMode模式的父类,用于处理不同模式的发送
    class AlPool {
        constructor() {}
    
        run() {};
        clean() {};
        queueTo(runnable) {};
    }
    
    

    序列化

    用于日志本地存储,避免日志丢失,每次序列化后,存储在window.localStorage

    class Serializable {
        readObject() {
            return "";
        }
    
        writeObject(str) {
    
        }
    }
    

    加密策略

    ==sorry 不能开放,可以根据具体情况在request请求或者在存储中做加密处理==

    总结

    • 保持模块独立性
    • 不要局限设计,根据具体需求变更或简化设计

    相关文章

      网友评论

        本文标题:JSSDK设计探索

        本文链接:https://www.haomeiwen.com/subject/urazrhtx.html