设计模式

单例模式

import Single from './single.js';

{
    let zhangsan = new Single("张三");
    let lisi = new Single("李四");
    let wangwu = new Single("王五");

    // console.log(zhangsan,lisi,wangwu);
    // console.log(zhangsan === lisi);//true
    // 实例化多少个依然还是一个,并且他们是相等的~
}

{
    // console.log(Single("张三"));
    let zhangsan = new Single("张三");
    let lisi = new Single("李四");
    console.log(zhangsan,lisi)
}
/* 
    单例模式:
        保证只有一个实例(实例化),也就是只有一个对象,不管实例化多少次,我们都始终是只有一个实例
        用处在哪些地方呢:
            1.业务需求:比如只需要一个播放器,当我们点击的时候就会有多个播放器.所以就需要使用单例模式
            2.性能:有些时候用多个实例和一个实例都是一样的情况下,可以考虑使用单例模式
        缺点:
            扩展性不强,对外比较封闭一些.
*/

/*
export default class Person{
    constructor(name){
        this.name = name;
    }
}
*/

/* 
// 使用类的静态属性 static -> 注意静态属性是属于类的属性!
export default class Person{
    static instance = null;
    constructor(name){
        if(Person.instance){//如果有就走这里
            return Person.instance;//return 代表下面代码也就不执行了
        }
        Person.instance = this;//直接让它赋值为 实例化对象;
        this.name = name;
    }
}
    缺点:
        在设计模式这块,一般情况下,对内是封闭的,对外是提供一些接口
        当别人修改类的静态属性是,这个单例模式就失效了
        Person.instance = null;
        所以这样的安全性并不是很高不是很好
*/

// 使用导出实例化对象
class Person{
    constructor(name){
        this.name = name;
    }
}
let instance = null;
export default function(...arg){
    if(!instance){
        instance = new Person(...arg);
    }
    return instance;
}

 工厂模式

{
    function Factory(name){
        let o = {};//创建
        // 添加
        o.name = name;
        o.fn = function(){
            console.log("...fn");
        }
        // 返还
        return o;
    }
    Factory();
}

{
    // 生成英雄的工厂
    class LuBan{
        constructor(){
            this.name = "鲁班七号";
        }
    }

    class YaSe{
        constructor(){
            this.name = "亚瑟";
        }
    }

    function Factory(heroName){
        switch(heroName){
            case "luban" :
                return new LuBan();
                break;
            case "yase" :
                return new YaSe();
                break;
            default:
                console.log("没有英雄");
                break;
        }
    }

    let luban = Factory("luban");
    console.log(luban);
    console.log( Factory("yase") )
}

 装饰者模式

{
    // 对对象进行 装饰
    class Hero{
        constructor(name){
            this.name = name;
        }
        fire(){
            console.log("释放技能");
        }
    }
    /* 
        这时候若想扩展一些功能,且不想在原有的类里面改动,和继承差不多~
        装饰者模式和继承的一些区别
            继承是可以添加一些方法
            装饰者模式一般是在方法里面进行 扩展一些功能
            一个是竖,一个是横
    */

    let fireDecoretor = function(hero){
        this.hero = hero;
    }
    fireDecoretor.prototype.fire = function(){
        this.hero.fire();
        console.log("伤害100点");
    }

    let luban = new Hero();
    let newLuban = new fireDecoretor(luban);
    newLuban.fire();// 释放技能 伤害100点
}

{
    // 装饰函数: 函数执行之前执行一些方法
    Function.prototype.before = function(beforeFn,...arg){
        beforeFn.call(this);//调用将要执行的方法
        return this.call(this,...arg);
    }

    function fn(){
        console.log("之前执行的函数");
        console.log(this);
    }

    // 要执行的函数
    function fireDecoretor(arg){
        console.log("要执行的函数",arg);
    }

    // 调用方法的时候:
    fireDecoretor.before(fn,"参数");
}

观察者模式/自定义事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<button class="btn">点击</button>
</body>
<script>
function fn1(){
    console.log("fn1...")
};
// 这是时候若想扩展 逻辑可以使用 观察者模式
function fn2(){
    console.log("fn2...");
}
// fn1();
// fn2();
// 但是有很多很多的时候,...

let handle = {};
addEvent("myEvent",fn1);
addEvent("myEvent",fn2);
removeEvent("myEvent",fn1);
trigger("myEvent");

// document.querySelector(".btn").addEventListener("click",fn1);
// document.querySelector(".btn").addEventListener("click",fn2);

// 如何实现像系统事件 一样有一个绑定事件呢?
// handle = { fn:[fn1,fn2],event:[fn1,fn2...] }
// 添加自定义事件
function addEvent(eventName,fn){
    if(typeof handle[eventName] === "undefined"){//代表没有这个数组
        handle[eventName] = [];//那就创建数组
    }
    handle[eventName].push(fn);
}
// 触发自定义事件
function trigger(eventName){
    for(let i = 0;i<handle[eventName].length;i++){
        handle[eventName][i]();
    }
}
// 移出自定义事件: 判断与删除;
function removeEvent(eventName,fn){
    for(let i = 0;i<handle[eventName].length;i++){
        if(handle[eventName][i]===fn){
            handle[eventName].splice(i,1);
            break;
        }
    }
}

</script>
</html>
export default class GameEvent{
    constructor(){
        handle = {}
    }
    addEvent(eventName,fn){
        if(typeof this.handle[eventName] === "undefined"){//代表没有这个数组
            this.handle[eventName] = [];//那就创建数组
        }
        this.handle[eventName].push(fn);
    }
    trigger(eventName){
        for(let i = 0;i<this.handle[eventName].length;i++){
            this.handle[eventName][i]();
        }
    }
    removeEvent(eventName,fn){
        for(let i = 0;i<this.handle[eventName].length;i++){
            if(this.handle[eventName][i]===fn){
                this.handle[eventName].splice(i,1);
                break;
            }
        }
    }
}

 

posted @ 2020-02-27 03:19  JackAfan  阅读(161)  评论(0)    收藏  举报
setTimeout(function(){ let aImg = document.querySelectorAll("img"); aImg.forEach(img=>{ img.alt = "" }) console.log("去除img-alt成功") },1000)