js常用设计模式

工厂模式

工厂模式就是使用函数创建对象 返回对象
避免多次创建对象
只需要传递一个合法的参数,就可以获取到你想要的对象,而无需知道创建的具体的细节
例如直接创建一个对象,将属性和方法全部放在这个对象里面

   function Factory(name,sex,age,job){
     //创建一个对象
     var obj={};
     obj.name=name;
     obj.sex=sex;
     obj.age=age;
     obj.job=job;
     obj.eat=function (){
     return this.name+"吃饭!";
     }

     return obj;
     }
     console.log(Factory("张三","男",18,"学生"));
     console.log(Factory("李四","男",22,"厨子"));

构造函数模式

1、构造函数模式就是把多个程序抽象成方法
2、使用构造函数的方法,既解决了重复实例化的问题,又解决了对象识别的问题。

原型模式

原型模式,原型对象上的属性和方法是共享的
空对象获取属性时 自身没有该属性 则原型对象上的属性充当默认值
设置空对象时 是给自己设置属性 不会修改原型对象的属性,因为原型对象上的属性是共享的
缺点:是原型对象属性方法的共享

function Person() {

    }
    Person.prototype = {
        constructor: Person,
        name: "默认值",
        sex: '',
        sleep: function (m) {
            return this.name + "睡觉" + m;
        }
    }
    //创建人
    var c1 = new Person();

    c1.name = "张三"
    console.log(c1.sleep("打呼噜"));

    var c2 = new Person();
    console.log(c2.sleep("不踏实"));

单例模式

单例模式 一个类提供一个实例,并且暴漏出一个全局访问点(闭包)
保证一个类只有一个实例,一般先判断实例是否存在,如果存在直接返回,不存在则先创建再返回,这样就可以保证一个类只有一个实例对象。
作用: (1)、保证某个类的对象的唯一性; (2)、模块间通信; (3)、防止变量污染

// 简单的单例
    function Person(name) {
        this.name = name;
    }
    //给上面的方法添加原型属性或方法
    Person.prototype.getName = function () {
        return this.name;
    }
    //自执行  执行函数  返回闭包的对象
  //就是一个单例方法
    var getObject = (function () {
        var instance = null;
        return function (name) {
            if (!instance) {
                instance = new Person(name);
            }
            //该函数的返回值对象   返回一个单独的对象
            return instance;
        }
    })();
    //调用单例模式
    console.log(getObject("张三").getName());//张三
    console.log(getObject("李四").getName());//张三
    console.log(getObject("王五").getName());//张三


    /*
     * 设置多个类对象  将单例的方法  抽象为一个共享方法
     *
     * callback  为回调函数
     *
     * 这个共享方法  不适用自执行
     * */
    var getInstance = function (callback) {
        var instance = null;
        return function () {
            if (!instance) {
                //实例化对象
                //apply  替换函数内部的this指针  执行前面的函数
                //this   指向window  可以可不写
                //console.log(this);
                instance = callback.apply(null, arguments);
            }
            return instance;
        }
    };

    console.log(getInstance(function () {
        console.log(arguments);
        var per = new Person("李四");
        return per;
    })().getName());
    console.log(getInstance(function () {
        var per = new Person("王五");
        return per;
    })().getName());


    function Animale(name,age){
        this.name=name;
        this.age=age;
    }
    Animale.prototype.getName=function (){
        return this.name;
    }

    console.log(getInstance(function () {
        var name = arguments[0];
        var age = arguments[1];
        var cat = new Animale(name, age);
        return cat;
    })("猫咪", 2).getName());
策略模式

策略模式属于对象行为型模式,主要针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响 到客户端的情况下发生变化。通常,策略模式适用于当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用
优点: 1、避免使用大量的if-else语句,使代码块简洁,易读。
2、符合设计原则中的开放-封闭原则,面向扩展开放,面向修改关闭。
3、复用性高
缺点:增加了许多策略类或者策略对象
例如转盘抽奖

var Sq = {
        gg: [],
        basePro: [],
        g: null,
        proindex: null,
        randominfo: function () {
            this.g = Math.random();
            for (var i = this.gg.length - 1; i >= 0; i--) {
                if (this.g <= this.gg[i]) {
                    this.proindex = i;
                }
            }
        }
    }

    var Rotate = {
        baseRotate: 1500,
        index: null,
        rotate: null,
        random: function () {
            Sq.randominfo();
            this.index = Sq.proindex;
        },
        rotateInfo: function () {
            this.rotate = this.index * 72 + Math.random() * 72;
        },
        allRotate: function () {
            this.random();
            this.rotateInfo();
            return this.baseRotate + this.rotate;
        }
    }


    function addPro(pro) {

        for (var key in pro) {
            Sq.basePro.push(key);
            Sq.gg.push(pro[key]);
        }
    }

    addPro({
        A: 0.1,
        B: 0.3,
        C: 0.5,
        D: 0.7,
        E: 1,
    });

    //重新随机

    console.log(Rotate.allRotate());
发布-订阅模式

发布订阅模式又叫观察者模式,定义对象间的一种一对多的关系,当一个对象的状态发生改变时,所有依赖它的对象都将的到通知
优点:对象之间的解耦
异步编程中,可以更松耦合的代码编写
缺点:创建订阅者本身要消耗一定的时间和内存
虽然可以弱化对象之间的联系,多个订阅者和发布者嵌套在一起的时候,程序难以跟踪和维护

  var observer = {
        subscribes: [],//订阅集合
        //订阅的方法
        subscribe: function (types, fn) {
            //检测types有没有订阅
            if (!this.subscribes[types]) {
                //创建订阅
                this.subscribes[types] = [];
            }
            //处理订阅的fn
            /*if(typeof fn=="function")
             {
             this.subscribes[types].push(fn);
             }*/
            typeof fn == "function" && this.subscribes[types].push(fn);
        },
        //执行订阅
        publish: function () {
            //检测当前的订阅是否存在
            var types = [].shift.call(arguments);//获取订阅着
            var fns = this.subscribes[types];
            //var name = [].shift.call(arguments).name;//获取订阅函数名称
            if (!fns || fns.length == 0) {
                return;
            }
            //开始执行
            var args = arguments;
            fns.forEach(function (handle) {
                console.log(handle.name);
                //handle.name  获取当前函数名称
               /* handle.name == name &&*/ handle.apply(this, args);
            });
            /*  for (var i = 0; i < fns.length; i++) {
             fns[i].apply(this, arguments);
             }*/
        },
        //删除订阅
        remove: function (types, fn) {
            //检测types  不存在  直接全部订阅移除
            if (!types) {
                this.subscribes = [];
                return;
            }
            //获取当前的订阅集合
            var fns = this.subscribes[types];

            if (!fns || fns.length == 0) {
                return;
            }
            //检测fn
            if (typeof  fn !== "function") {
                return;
            }
            //删除订阅
            fns.forEach(function (handle, index) {
                if (handle == fn) {
                    fns.splice(index, 1);
                }
            });
        }
    }

    /*
     * 模拟  maodou  定飞机票   火车票
     * */
    function getPiao(res) {
        console.log("订购:", res);
    }
    function getHose(res) {
        console.log("订:", res, "酒店");
    }
    observer.subscribe("maodou", getPiao);
    observer.subscribe("maodou", getHose);
    observer.subscribe("maodou", function () {
        console.log("先去吃饭!");
    });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值