1

观察者模式

需求:有人加入订阅或移除的时候,发出通知,告知订阅的所有人

class Publisher {
    constructor(){
        this.obverves = [];
    }
    add(obj){
        if(!this.obverves.includes(obj)){
            this.obverves.push(obj)
        }
    }

    remove(obj){
        this.obverves = this.obverves.filter(item=>item !== obj);
    }

    noti(message){
        this.obverves.forEach(item => {
            item.update(message)
        });
    }
}




class Subscribe {
    constructor(name, age){
        this.name = name;
        this.age = age;
    }

    update(message){
        console.log(message)
    }
}

const pub = new Publisher();

const p1 = new Subscribe('张三', 18);
pub.add(p1);
pub.noti('欢迎' + p1.name + '加入');

const p2 = new Subscribe('李四', 20);
pub.add(p2);
pub.noti('欢迎' + p2.name + '加入');

pub.remove(p1);
pub.noti( p1.name + '已退出订阅');

运行结果:
图片描述

发布订阅模式

需求:处理不同订阅类型 的人,发送特定订阅信息的时候,只有订阅了的人可以收到

class Publisher {
    constructor(manager){
        this.manager = manager;
    }

    noti(message, type){
        this.manager.update(message, type);
    }
}

class PublishManager {
    constructor(){
        this.sub = {
            'javaScript': [],
            'php': [],
            'python': []
        };
    }

    add(obj){
        if(!this.sub[obj.type]){
            return false;
        }
        if(!this.sub[obj.type].includes(obj)){
            this.sub[obj.type].push(obj)
        }
    }

    remove(obj){
        this.sub[obj.type] = this.sub[obj.type].filter(item=>item !== obj);
    }

    update(message, type){
        if(!this.sub[type]) return ;
        this.sub[type].forEach(item => {
            item.update(message)
        });
    }
}



class Subscribe {
    constructor(name, age, type){
        this.name = name;
        this.age = age;
        this.type = type
    }

    update(message){
        console.log(this.name + "收到订阅:" + message)
    }
}
const pubMag = new PublishManager();
const pub = new Publisher(pubMag);


const p1 = new Subscribe('张三', 18, "javaScript");
pubMag.add(p1);
const p2 = new Subscribe('李四', 20, "php");
pubMag.add(p2);

pub.noti("这是来自javaScript的订阅", "javaScript");
pub.noti("这是来自php的订阅", "php");

运行结果:
图片描述

单例设计模式

需求: 只允许只有一个实例

const GetSingal = (function(){
    let instance;
    return function(name){
        if(!instance){
            console.log(instance)
            instance = {
                name: name
            }
        }
        return instance;
    }
})()


const p1 = new GetSingal("张三");
const p2 = new GetSingal("李四");
console.log(p1);
console.log(p2);

运行结果:
图片描述

策略模式

需求:针对不同的人群,划分不同的折扣

const childTicket = {
    count : 0.7,
    type : 'child'
}

const adultTicket = {
    count : 1,
    type : 'adult'
}


class TicketManager {
    constructor(price){
        this.price = price;
        this.types = {};
    }

    addType(option){
        if(!this.types[option.type]){
            this.types[option.type] = option.count;
        }
    }

    getPrice(num, type){
        if(!this.types[type]){
            return ;
        }
        return num * this.price *  this.types[type];
    }
}

const tm = new TicketManager(200);
tm.addType(childTicket);
tm.addType(adultTicket);

const p1 = tm.getPrice(2, "child");
console.log('买两张儿童票的总价是:'+ p1);
const p2 = tm.getPrice(1, "adult");
console.log('买1张成人票的总价是:'+ p2);

说明:将每一种行为独立为一个对象,每个对象都是一种策略。不用写庞大的switch语句
运行结果:

图片描述

代理模式

需求:将复杂的事情交给别人做,比如买票麻烦,交给专人去做

class Person {
    constructor(name){
        this.name = name;
        this.tickets = [];
    }

    async buy(ticket){
        await new Promise(resolve=>setTimeout(resolve, 3000));
        console.log(this.name+ '排了三小时的队,最后买到了票');
        this.tickets.push(ticket)
    }

    receive(ticket){
        console.log(this.name + "收到了" + ticket)
        this.tickets.push(ticket)
    }
}

class ProxyBuy {
    static async buy(person, ticket){
        await new Promise(resolve=>setTimeout(resolve, 1000));
        console.log('专业的代理排了一小时的队,很快买到了票');
        person.receive(ticket)
    }
}

const p1 = new Person("张三");
const p2 = new Person("李四");
p2.buy("火车票");
ProxyBuy.buy(p1, "火车票");

运行结果:
图片描述

装饰者模式

需求:给某个对象动态的增加一些功能,但不能改变原来的对象

function WebEnginner(name){
    this.name = name;
}

WebEnginner.prototype.skill = function(){
    console.log('掌握JavaScript')
}

function Es6(we){
    this.we = we;
}

Es6.prototype.skill = function(){
    this.we.skill();
    console.log("掌握es6");
}

function NodeJs(we){
    this.we = we;
}

NodeJs.prototype.skill = function(){
    this.we.skill();
    console.log("掌握nodeJs");
}

const we = new NodeJs(new Es6(new WebEnginner("张三")));
we.skill();

运行结果:

clipboard.png

工厂模式

需求:批量生产同一类型的对象

function car(name, price, number){
    const o = new Object();
    o.name = name;
    o.price = price;
    o.number = number
    return o;
}


var car1 = car("丰田", 100000, 452485);
var car2 = car("保时捷", 1000000, 123456);
console.log(car1);
console.log(car2);

运行结果:
图片描述

组合模式

特点:构造函数模式用来定义实例属性,而原型模式用于定义方法和共享属性。这样可以最大限度的节省内存,且支持向构造函数传参。

function Person(name, age){
    this.name = name;
    this.age = age;
}

Person.prototype.sayName = function(){
    console.log(this.name)
}

const p1 = new Person("张三", 18);
p1.sayName();

组合继承

特点:构造函数模式用来定义实例属性,而原型模式用于定义方法和共享属性。这样可以最大限度的节省内存,且支持向构造函数传参。同时避免了原型链和借用构造函数的缺陷,成为最常用的继承模式

function Parent(money, house){
    this.momey = money;
}

Parent.prototype.sayHello =function(){
    console.log("hello");
}

function Person(name, sex, money){
    this.name = name;
    this.sex= sex;
    Parent.call(this, money);
}

Person.prototype = new Parent();
Person.prototype.eat = function(){
    console.log("吃饭");
}

const p1 = new Person('张三', "男", 100000);
console.log(p1)
p1.sayHello();
p1.eat();

运行结果:
图片描述


Ryan
91 声望3 粉丝