结对编程(前后端分离)

Posted frankyi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结对编程(前后端分离)相关的知识,希望对你有一定的参考价值。

成员:

  巫培杰:3117004669

  易俊楷:3117004677

 

 一、Github项目地址

 前端代码:https://github.com/JakeYi/Paring-project

后端代码:https://github.com/blanche789/softpairing

二、PSP表格

PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning 计划 20 20
· Estimate · 估计这个任务需要多少时间 30 30
Development 开发 1520 1550
· Analysis · 需求分析  90 85
· Design Spec · 生成设计文档 60 50
· Design Review · 设计复审  35 45
· Coding Standard · 代码规范 90 80
· Design · 具体设计 60 60
· Coding · 具体编码 1000 1100
· Code Review · 代码复审 100 120
· Test · 测试(自我测试,修改代码,提交修改) 90 110
Reporting 报告 110 150
· Test Report · 测试报告 60 50
· Size Measurement · 计算工作量 40 30
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 60 70
Total  总计 1720 1760

三、效能分析

  生成一万道题目用的时间是766ms

        技术图片

 

 

四、设计实现过程

  本项目是前后端分离的项目,我是负责前端的技术,前端采用的技术栈是jquery框架,简化了开发流程。前端与后端的交互是通过接口进行的,实现了真正的分工合作。

  主要流程是编写静态页面,然后逐一实现功能。

  关键函数通过四个主要的对象编写

  1. Paging类 切换分页面

  2. Subject类 获取题目和答案并放置到dom节点上

  3. Match类 进行题目的校队

  4.Download类 进行题目的下载和答案的下载

  技术图片

 

 

 

五、代码说明

1.Subject对象 获取题目和答案并放置到dom节点上

var Subject = {
    init: function () {
        var _this = this
        this.$main = $(".content")
        this.$input = this.$main.find(".operate input")
        this.$confirm = this.$main.find(".operate a")
        this.$second = $(‘.second‘)
        this.$subject = $(‘#subject‘)
        this.$answer = $(‘#answer‘)
        this.$tTbody = this.$subject.find(‘.chart .manifest tbody‘)
        this.$aTbody = this.$answer.find(‘.chart .manifest tbody‘)

        this.bind()

    },
    bind: function () {
        var _this = this
        var string = new Array()
        this.$confirm.click(function (e) {

            _this.$inputValue = _this.$input[0].value
            if ((_this.$inputValue.match(/^[0-9]+,[0-9]+$/g)) == null) {
                console.log(‘输入了错误的数据‘)
                e.preventDefault();
            } else {
                _this.$main.addClass(‘hide‘)
                _this.$second.removeClass(‘hide‘)
                _this.strs = new Array()
                strs = _this.$inputValue.split(",")
                _this.questionNum = parseInt(strs[0])
                _this.numericalRange = parseInt(strs[1])
                console.log(_this.$input)
                console.log(_this.$inputValue)
                console.log(_this.questionNum)
                console.log(_this.numericalRange)
                console.log(typeof _this.questionNum)
                console.log(typeof _this.numericalRange)
                _this.getData(function (result) {
                    _this.renderData(result)

                })
            }

        })

        this.$tTbody.click(function () {
            // console.log(‘click title_tbody‘)
        })
        this.$aTbody.click(function () {
            // console.log(‘click answers_tbody‘)
        })
    },
    getData: function (callback) {
        var _this = this
        var allData = {
            questionNum: _this.questionNum,
            numericalRange: _this.numericalRange
        };
        $.ajax({
                url: ‘/generate‘,
                type: ‘POST‘,
                contentType: "application/json",
                dataType: "json",
                data: JSON.stringify(allData)
            })
            .done(function (ret) {
                // console.log(ret)
                callback(ret)
            })
            .fail(function (err) {
                console.log("出错了")
            })
            .always(function () {
                console.log("end...")
            })
    },
    renderData: function (data) {
        var _this = this
        data.forEach(function (item) {
            // console.log(item);
            var $nodeTit = _this.createTitle(item)
            var $nodeAns = _this.creatAnswer(item)
            _this.$tTbody.append($nodeTit)
            _this.$aTbody.append($nodeAns)
        })
    },
    creatAnswer: function (node) {
        var $node = $(`
        <tr>
        <td >${node.qid+1}</td>
        <td>${node.exercise}</td>
        <td class="answer">${node.answer} </td>
        </tr> `)
        return $node
    },
    createTitle: function (node) {
        var $node = $(`
        <tr class="title${node.qid+1}">
        <td >${node.qid+1}</td>
        <td>${node.exercise}</td>
        <td>
        <input type="text">
        </td>
         <td class="check_answer"></td>
        </tr>
        `)
        return $node
    }

}

2. Match类 进行题目的校队

var Match = {
    init: function () {
        var _this = this
        this.$main = $(‘#subject‘)
        this.$second = $(‘#answer‘)
        this.$mainTbody = this.$main.find(‘.chart .manifest tbody‘)
        this.$secondTbody = this.$second.find(‘.chart .manifest tbody‘)

        this.$check = this.$main.find(‘.chart .check‘)
        this.bind()
    },
    bind: function () {
        var _this = this
        _this.$check.click(function () {
            _this.$text = _this.$mainTbody.find(‘input‘)
            _this.$answer = _this.$secondTbody.find(‘.answer‘)
            _this.$checkAnswer = _this.$mainTbody.find(‘.check_answer‘)
            _this.check()
            console.log(‘check‘)
        })

    },
    check: function () {
        var _this = this
        for (let i = 0; i < _this.$answer.length; i++) {
            console.log( _this.$answer[i].innerText)
            console.log( _this.$text[i].value)
            if (_this.$answer[i].innerText == _this.$text[i].value + ‘ ‘) {
                _this.$checkAnswer.eq(i).html(‘true‘)
                console.log("right")
            } else {
                _this.$checkAnswer.eq(i).html(‘false‘)
                console.log("error")

            }
        }
    }
}

3.Download类 进行题目的下载和答案的下载

var Download = {
    init: function(){
        var _this = this
        this.$third = $(‘#function‘)
        this.$file = this.$third.find(‘.file‘)
        this.$answer = this.$third.find(‘.answer‘)
        this.bind()
    },
    bind: function(){
        var _this = this
        _this.$file.click(function(){
            console.log(‘click file‘)
            var xhr = new XMLHttpRequest()
            xhr.open(‘POST‘, "/download", true)
            xhr.responseType = ‘blob‘

            xhr.onload function() {
                if (this.status === 200) {
                    var responseHeaders = xhr.getAllResponseHeaders().toLowerCase();
                    var fileName = responseHeaders.match(/w+.txt/g)
                    var blob = this.response
                    var a = document.createElement(‘a‘)
                    a.download = `${fileName}`
                    a.href = window.URL.createObjectURL(blob)
                    a.click()
                }
            }
            xhr.send("0")
        })
        _this.$answer.click(function(){
            console.log(‘click answer‘)
            var xhr = new XMLHttpRequest()
            xhr.open(‘POST‘, "/download", true)
            xhr.responseType = ‘blob‘

            xhr.onload function() {
                if (this.status === 200) {
                    var responseHeaders = xhr.getAllResponseHeaders().toLowerCase();
                    var fileName = responseHeaders.match(/w+.txt/g)
                    var blob = this.response
                    var a = document.createElement(‘a‘)
                    a.download = `${fileName}`
                    a.href = window.URL.createObjectURL(blob)
                    a.click()
                }
            }
            xhr.send("1")
        })
    }
}

4.Paging类 切换分页面

var Paging = {
    init: function () {
        this.$tab = $(‘footer>div‘)
        this.$page = $(‘main>section‘)
        this.bind()
        console.log("123")
    },
    bind: function () {
        var _this = this
        _this.$tab.on(‘click‘, function () {
            console.log(‘tab click...‘)
            var $this = $(this)
            var index = $this.index()
            $this.addClass(‘active‘).siblings().removeClass(‘active‘)
            _this.$page.eq(index).fadeIn().siblings().hide()
        })
    }
}

 

六、测试运行

1.初始界面

技术图片

 

 2. 题目

技术图片

 

 3. 答案

技术图片

 

 4.下载功能

技术图片

 

 5. 校队功能

技术图片

 

 6.下载题目

技术图片

 

 7.下载答案

技术图片

 

 

七、项目小结

本次项目通过真正的前后端分离,体验到实际开发中的感觉,结对开发的时候更多的是需要迁就与包容,当出现BUG的时候需要耐心的应对,不要因为一些很困难的问题就选择放弃。

开发过程中搭档提供的接口需要很多的耦合代码,下了比较大的功夫,获取数据的时候出现了差错,跳转404页面的次数比较多,一度产生奔溃情绪,实际编码过程中也因为获取数据的时候测试使用的是假数据所以出现了和结果的偏差。

我觉得在下次的开发过程中,如果按照产品,设计,后端,前端这样的开发路线来说,无论对于产品的质量,还是对于开发者来说,会是一个不错的选择。

本次项目比较匆忙,如有未发现的漏洞,请大家谅解。

以上是关于结对编程(前后端分离)的主要内容,如果未能解决你的问题,请参考以下文章

前后端分离的好处有哪些?

什么是前后端分离与前后端不分离

前后端分离开发模式的 mock 平台预研

谈谈前后端分离及认证选择

jsp与前后端分离谁更快

[转] 前后端分离开发模式的 mock 平台预研