zoukankan      html  css  js  c++  java
  • Model 编程

    1. Model 编程

    1.1 介绍

    Model 编程, 即模块化编程; 是指将业务分割成为一个个模块, 每个模块拥有特定的功能, 通过继承和组合完成功能的组合; 它其实就是面向对象编程的拓展.

    Model 编程最适合的内容为定义前端API 内容, 将API 实现封装, 在封装层实现数据的处理和转发; UI 界面只需要调用数据即可, 不需要处理数据的目的; 达到在各个分层中, 只需要集中处理本层的核心内容, 其他内容直接通过调用获取.

    1.2 为什么要使用Model 编程

    在前端界面中, 请求数据的方法有: AJAX, Axios, Fetch, 在这里我们约定一下: 我们将数据请求的方法称为API

    API 可分为如下几个组成部分:

    1. API的方法
    2. 数据请求的接口
    3. 数据的处理

    按照一般思维, 我们会将这些内容合并处理, 即在一个界面中先拿到数据, 处理数据之后然后渲染到界面中.

    这种方式确实写起来很方便, 因为我们只需要关注业务逻辑即可

    但是, 如果此时业务场景变更了:

    如果API 方法变了, 那么是不是我们必须修改所有界面的请求?

    如果请求的接口变了, 那么我们是不是需要修改所有页面的URL?

    如果后端擅自把数据格式变了, 那么我们是不是需要整理寻找业务处理逻辑, 然后去修改?

    如果项目小, 可能上面的问题不会是问题, 但是如果一个项目可能有大量迭代维护的需求, 我们就需要考虑抽象的合理性和迭代的成本, 因为数据请求涉及的层次往往会非常多, 如果不进行合理地封装, 那么会导致迭代成本非常高(修改内容过多)

    而Model 编程就可以解决上述问题, 下面我们来介绍一下Model 对于API 的处理思路

    1.3 Model API 处理思路

    各个界面对应的功能:

    1. 后端Server: 后端服务器, 用于提供请求的数据信息
    2. API: 实现请求方式(AJAX, Axios, Fetch)的封装
    3. Professinal API: 整合请求, 将请求模块化; 例如, 一个项目可以分为如下模块: 用户信息模块, 权限模块, 具体业务模块, 数据可视化模块
    4. Model 抽象层: 定义Model 通用的方法
    5. Model: 先通过调用Professinal API 拿到后端传递过来的原始数据, 然后处理数据
    6. UI 界面: 想Model 层调用处理之后的数据, 然后进行页面渲染

    2. Model 的分层

    3.1 服务器

    对于前端来说, 服务器是指后端提供的接口内容;

    3.2 API 基类

    一个项目用来请求数据的方式, 一般项目leader 会对请求方式进行基本封装, 最常见的数据请求方式是ajax
    实例代码:

    const _ajax = (method, url, data) => {
        let p = new Promise((resolve, reject) => {
            // Fetch API
            // axios
            let r = new XMLHttpRequest()
            r.open(method, url, true)
            r.setRequestHeader('Content-Type', 'application/json')
            r.onreadystatechange = () => {
                if (r.readyState === 4) {
                    if (r.status === 200) {
                        let response = JSON.parse(r.response)
                        resolve(response)
                    } else {
                        reject({
                            success: false,
                        })
                    }
                }
            }
            r.send(data)
        })
        return p
    }
    
    class Ajax {
        constructor(baseUrl) {
            // 定义统一的接口,这样后面就可以直接引用了;后期如果需要更改这样也容易改
            this.baseUrl = baseUrl || 'http://localhost:8000/'
            // console.log(this.baseUrl)
        }
        get(path) {
            let url = this.baseUrl + path
            console.log(url)
            return _ajax('GET', url, '')
        }
    
        post(path, data) {
            let url = this.baseUrl + path
            data = JSON.stringify(data)
            return _ajax('POST', url, data)
        }
    }
    
    export default Ajax
    

    3.3 业务API

    在一个项目中, 业务可以分为很多个模块;
    比如在之前公司上班的时候, 自己负责的就是图表模块, 表格显示模块, 首页的显示模块
    这些模块如果是自己负责, 其他开发人员不参与其中的话, 我们可以将这些模块按照model 编程处理, 这样虽然最开始加大了一点工作量, 但是到后期很容易维护!
    如果是多个人一同负责一个模块, 那么使用model 处理就需要和其他人商量着来.

    在业务API 这一层, 我们将一个模块的请求汇总在一起集中处理
    实现代码

    import Api from './api'
    
    class IpApi extends Api {
        constructor(props) {
            super('https://httpbin.org/ip');
        }
    
        getIp() {
            return this.get('')
        }
    }
    
    export default IpApi
    

    3.4 model模块API

    这一层主要是做数据处理, 将后端传递过来的数据处理成我们想要的数据格式, 然后定义一个函数进行数据转发, 转发的地点是应用层

    import IpApi from '../api/IpApi'
    import Model from './Model'
    
    class IpModel extends Model{
        constructor() {
            super()
            this.api = new IpApi()
        }
    
        getIp() {
            let p = this.api.getIp()
            return p.then((ip) => {
                return ip.origin
            })
        }
    }
    
    export default IpModel
    
    

    3.5 业务层

    在这一层, 我们直接拿到了我们需要的数据格式, 因此只用将重心集中在页面渲染即可. 我们只需要关系渲染的逻辑, 而不需要关系数据的获取以及处理过程.

    3. demo

    3.1 场景描述

    现在需要渲染两个数据:

    1. 通过接口: https://httpbin.org/ip 接口获取IP地址
    2. 通过接口: https://free-api.heweather.net/s6/weather/now?location=${location}&key=cc8fb05bb74c41f3ad6121e9f2826eb7 获取城市的天气

    3.2 链接

    Model Demo

  • 相关阅读:
    《代码大全2》阅读笔记08Chapter 15 Using Conditionals
    《代码大全2》阅读笔记09Chapter 16 Controlling Loops
    《代码大全2》阅读笔记12 Chapter 19 General Control Issues
    《代码大全2》阅读笔记13 Chapter 22 Developer Testing
    [转帖]Dictionary, SortedDictionary, SortedList 横向评测
    《代码大全2》阅读笔记07Chapter 12 Fundamental Data Types
    《代码大全2》阅读笔记11 Chapter 24 Refactoring
    《代码大全2》阅读笔记14 Chapter 23 Debugging
    New Concept English 3 01 A Puma at large
    (ZT)委托和事件的区别
  • 原文地址:https://www.cnblogs.com/oulae/p/13047358.html
Copyright © 2011-2022 走看看