ES6设计模式

个人学习笔记 没啥说明转折,有时间补充一下

结构型设计模式

外观模式

用户简化底层代码方式,或者兼容性。

ES5
// 获取事件对象
var getEvent = function(event) {  
    return event || window.event;
}
// 获取目标元素
var getTarget = function(event) {  
    var event = getEvent(event);
    return event.target = || event.srcElement;
}
// 阻止默认行为
var preventDefault = function(event) {  
    var event = getEvent(event);
    // 标准
    if(event.preventDefault) {
        event.preventDefault();
    // IE
    } else {
        event.returnValue = false;
    }
}

document.click = function(e) {  
    preventDefault(e);
    if(getTarget(e) !== document.getElementById('myID')) {
        hideID();
    }
}

// 小型代码库
var Lib = {  
    getId : function(id) {
        return document.getElementById(id);    
    },
    css : fucntion(id, key, value) {
        document.getElementById(id).style[key] = value;
    },
    attr : function(id, key, value) {
        document.getElementById(id)[key] = value;
    }
    html : function(id, html) {
        document.getElementById(id).innerHTML = html;
    }
    on : function(id, type, fn) {
        document.getElementById(id)['on' + type] = fn;
    }
}
ES6

核心概念就是提供一个统一的API 做底层的兼容和处理代码简化。

let nextTick = (global.setImmediate == undefined) ? process.nextTick : global.setImmediate;  

适配器模式

框架耦合,参数适配 可以理解为电源转接头。

ES5
function doSomeThin(obj) {  
    var _adapter = {
        name : '哈哈哈',
        title : '设计模式',
        age : 25,
        color : 'red',
        size : 100  
    }

    for(var i in _adapter) {
        _adapter[i] = obj[i] || _adapter[i];
    }
}

// 服务端数据无论如何变化,只返回程序需要数据。
function ajaxAdapter(data) {  
    return [data['key1'], data['key2'], data['key3']];
}
$.ajax({
    url : 'someAdress.php',
    success : function(data, status) {
        doSomeThing(ajaxAdapter(data));
    }
});
ES6

根据数据需要keys里的参数需要 来处理ajax请求来的数据

let keys = ['key1', 'key2', 'key3'];  
let adapter = (data) => {  
    let tmp = [];
    for(let k of keys) {
        tmp.push(!data[k]? 'none' : data[k]);
    }
    return tmp;
};
console.log(adapter({  
    'key1' : 'haha',
    'key2' : 'heihei',
    'key4' : 'hoho',
}));

代理模式

通过继承的方式获得父类的方法,并在代理中做一些需要的操作,比如延迟,比如修改数据。

ES5
function SuperClass() {};  
SuperClass.prototype.doSomeThing = function() {  
    // todo
    alert(1);
}

function Proxy() {}  
Proxy.prototype = new SuperClass();  
Proxy.prototype.doSomeThing = function(){  
    var _this = this;
    setTimeout(function(){
        _this.__proto__.doSomeThing();
    }, 2000);
}
var p = new Proxy();  
p.doSomeThing();  
ES6
class SuperClass {  
    constructor() {

    }
    doSomeThing() {
        alert(1);
    }
}
class Proxy extends SuperClass {  
    constructor() {

    }
    doSomeThing() {
        setTimeout(super.doSomeThing(), 2000);
    }
}

装饰者模式

与适配者模式不同,装饰者模式是对原有功能的增加和拓展

ES5
var decorator = function(input, fn) {  
    var input = document.getElementById(input);
    if(typeof input.onclick === 'function') {
        var oldClickFn = input.onclick;
        input.onclick = function() {
            oldClickFn();
            // 执行新增回调
            fn();
        }
    } else {
        input.click = fn;
    }
}
ES6
let decorator = (fn) => {  
    return (name) => {
        console.log('Hello' + fn(name));
    }
}

let showName = (name) => {  
    return name;
}

showName = decorator(showName)

showName('Yuan Liang');  

桥接模式

将实现层与抽象层解藕分离,两部分可以独立变化。

ES5
function Speed(x, y) {  
    this.x = x;
    this.y = y;
}
Speed.prototype.run = function() {  
    console.log('run');
}
function Skin(c) {  
    this.c = x;
}
Skin.prototype.changeColor(color) {  
    this.c = color;
}
// 具体类和抽象类的桥梁
function Ball(x, y, cl) {  
    this.speed = new Speed(x, y);
    this.skinColor = new Skin(cl);
}
Ball.prototype.init = function() {  
    this.run();
}
function People(x, y, cl) {  
    this.speed = new Speed(x, y);
    this.skinColor = new Skin(cl);
}
People.prototype.init = function() {  
    this.run();
}

性能有待考量。 ES6 就就是一些类的继承 extends

组合模式

可用于组建的拼装。

ES5
// 虚拟类
var News = function() {  
    this.children = [];
    this.element = null;
}
News.prototype = {  
    init : function() {
        throw new Error("重写方法");
    },
    add : function() {
        throw new Error("重写方法");
    }
    getEl : function() {
        throw new Error("重写方法");
    }
}

var Container = function(id, parent) {  
    News.call(this);
    this.id = id;
    this.parent = parent;
    this.init();
}
inheritPrototype(Container, News);  
Container.prototype.init = function() {  
    this.element = document.creatElement('ul');
    this.element.id = this.id;
    this.element.className = 'news-container';
}
Container.prototype.add = function(child) {  
    this.children.push(child);
    this.element.appendChild(child.getEl());
    return this;
}
Container.prototype.getEl = function() {  
    return this.element;
}

var Item = function(classname) {  
    News.call(this);
    this.classname = classname || '';
    this.init();
}
inheritPrototype(Item, News);  
Item.prototype.init = function() {  
    this.element = document.creatElement('li');
    this.element.className = this.classname;
}
Item.prototype.add = function(child) {  
    this.children.push(child);
    this.element.appendChild(child.getEl());
    return this;
}
Item.prototype.getEl = function() {  
    return this.element;
}

var new = new Container('news', document.body);  
new.add(  
    new Item('news-item').add(
        // iconnews类懒得写没实现大概的意思就是创建一个icon类型的结点
        new IconNews('标题标题', 'http://www.youku.com', 'video');
    ).add(
        new Item('news-item').add(
            new ImageNews('标题标题', 'image/1.jpg', 'http://www.youku.com', 'video');
        )
    )
)
ES6

ES6也可以用类的多重继承来解决该问题。

享元模式

处理数据比较大时提高效率。区分内部状态和外部状态

ES5
var Flyweight = function() {  
    var created = [];
    function create() {
        var dom = document.createElement('DIV');
        document.getElementById('container').appendChild(dom);
        created.push(dom);
        return dom;
    }
    return {
        getDiv : function() {
            if(created.length < 5) {
                return create();
            } else {
                var div = created.shift();
                created.push(div);
                return div;
            }
        }
    }
}
ES6
class Shape {  
    constructor(w) {
        this.w = w;
    }
    static draw() {

    }
}

class Circle extends Shape {  
    constructor(color) {
        super();
        this.color = color;
    }
    draw() {
        console.log('画' + this.color + '圆');
    }
}

class FlyWeightFactory {  
    constructor() {

    }
    getShape(color) {
        return new Circle(color);
    }

}

var shape1 = new FlyWeightFactory().getShape('红色');  
shape1.draw();  
var shape2 = new FlyWeightFactory().getShape('黄色');  
shape2.draw();  
var shape3 = new FlyWeightFactory().getShape('蓝色');  
shape3.draw();  

Yuan Liang

资深程序渣、秧歌队贝斯手、摄影百拍王、意淫旅行家、正经的令人发指!

http://yuanliang.io
—Read This Next—

ES6设计模式(二)


创建型设计模式学习笔记 个人学习笔记 所以没有说明细节,有时间补充一下。如有错误欢迎指正批评:) 工厂模式 ES5前 var BookFactory = function(subType, superType) { if(typeof BookFactory[supe
—You Might Enjoy—

该抛弃grunt,gulp了?


今天看了一篇不错的文章,和我之前想的一些疑问不谋而合。记录一下:) 链接: 英文原文 ; 中文翻译 文中提到的三个核心问题是实实在在的。 对插件作者的依赖 令人沮丧的调试 脱节的文档 跟我之前的痛点差不多的是,之前的几个项目在使用gulp时担心gulp的插件更新不够及时,或者一些