bojue/bojue.github.io

JavaScript设计模式-命令模式

bojue opened this issue · 0 comments

bojue commented

JavaScript设计模式-命令模式

命令模式:通过将请求和实现解耦,单独封装成对象,从而实现不同的请求和客户端的实现参数化。

命令模式是一种常见是设计模式,即使你不知道它准确的概念。

打印模板

我们曾经封装一份打印多设备报表,支持多页,分类,标题,页面均可配置的开发需求,就使用到了命令模式的相关**,下面我用一段伪代码实现相关的一些业务,为了说明问题,假设我们的数据量不超过单页,标题,页码均支持。

let PageTemplate = (function(pageInfo) {
    let Template = {
        title: function(titVal) {
            let temp_tit = `<p class="title">${titVal}</p>`;
            return temp_tit;  
        },
        content: function(val, paramsArray, type) {
            if(!(val && paramsArray instanceof Array )) return;
            let temp_content = '';
            let paramsLen = paramsArray.length;
            let comp_lines_title  = '';
            for(let pi = 0; pi< paramsLen;  pi++) {
                let param = paramsArray[pi];//获取每个json的位置
                comp_lines_title += `<span>${param}</span>`;
            }
            comp_lines_title = `<li class='lines-title'>${comp_lines_title}</li>`;

            if(val instanceof Array || type === 'list') {
                let len = val.length;
                let temp_lines = comp_lines_title;
                for(let i=0;i<len;i++) {
                    let lowValue = val[i]; //获取每行的值
                    let temp_line = ''; //行元素和值组成的行模板
                    for(let pi = 0; pi< paramsLen;  pi++) {
                        let param = paramsArray[pi];//获取每个json的位置
               
                        let itemByLineVal = lowValue[param];
                        let itemByLine_temp = `<span>${itemByLineVal}</span>`;
                        temp_line += itemByLine_temp;
                    }
                    temp_lines += `<li class='line'>${temp_line}</li>`;
                }
                temp_content = `<ul class="content">${temp_lines}</ul>`;
            } else if(type === 'json') {
                let temp_by_json = ''; 
                for(let pi = 0; pi< paramsLen;  pi++) {
                    let param = paramsArray[i];
                    let item_val = val[param]; //获取参数对于的值
                    let item_temp = `<li><span>${item_val}</span></li>`;
                    temp_by_json += item_temp;
                }
                temp_content = `<ul class='content'>${temp_by_json}</ul>`;
            }
            return temp_content;
        },
        pageNumber: function(num, unitBool) {
            let temp_page_number = '';
            let pageNumberVal = unitBool===false?`第 ${num} 页`: `${num}`; 
            temp_page_number = `<p class="pageNumber">${pageNumberVal}</p>`
            return temp_page_number;
        }
    }

    return function(pageInfo) {
        if(!(pageInfo && pageInfo['content'] && pageInfo['pageNum'])) return;
        let title = pageInfo['title'];
        let content_val = pageInfo['content']['val'] 
        let content_params = pageInfo['content']['params'];
        let content_type = pageInfo['content']['type'];
        let num = pageInfo['pageNum']['num'];
        let unitBool = pageInfo['pageNum']['unitBool'];
        let htmlString = `
            ${Template.title(title)}
            ${Template.content(content_val, content_params, content_val)}
            ${Template.pageNumber(num, unitBool)}
        `;
        return htmlString;
    };
})()

let page = {
    title: '测试标题',
    content: {
        val: [{
            name:"javaScript",
            type:"web"
        },
        {
            name:"node",
            type:"server"
        }],
        params: ['name', 'type'],
        type: 'list'
    },
    pageNum: {
        num:1,
        unitBool: true
    }
}
let temp = PageTemplate(page)

我们使用了PageTemplate()函数拼接了一段HTML代码,在PageTemplate内部,我们封装了三个具体的拼接逻辑,title()函数我们处理标题,content()函数我们处理内容,pageNumber()函数处理页码。

在客户端我们实现了参数化之后,所以复杂了处理逻辑封装到了单独的对象,我们每次需要创建不同的HTML页面,只需要配置参数对象,不需要考虑具体的实现逻辑。

参考