zoukankan      html  css  js  c++  java
  • 设计模式(上)

    JAVAScript 创建对象 的13设计模式(上)


    要掌握设计模式,首先接触的是 高阶函数(higher-order function)[1]

    高阶函数的应用:

    • 回调函数:

      • 事件、ajax、所有涉及到异步通信的几乎都是回调函数()node.js
    • dom事件

    一、单例模式

    理论: 整个程序只包含一个实例;保证实例公有一个类,
    并提供一个访问它的全局访问点(实例化的都指向同一区域)。

    优点:节约内存;在 JavaScript 里,单例作为一个命名空间提供者,
    从全局命名空间里提供一个唯一的访问点来访问该对象,避免全局污染。

    缺点:字面量实现方式即使不用也占用内存,延迟方式,
    当调用 getInstance的时候才分配内存,如果单例对象非常复杂,
    则延迟模式(惰性加载)更好。

    1 字面量形式

        通过 对象字面量 的形式(json格式)

    var obj = {
        name: 'wang',
        showName: function() {
            console.log(this.name);
        }
    };
    var o1 = obj;
    var o2 = obj;
    <!-- o1 === o2 -->
    // 复杂类型是将obj变量存于栈中,通过指针指向堆中的存储空间
    

    2.通过 构造函数 的方式(改变指针指向,确保只开辟一个空间)

    function Obj(){
        <!-- 为保证只有一个实例,定义一个变量,判断是否有该实例 -->
        if(Obj.a !== undefined) {
            //第二次实例化的时候通过保存的变量改变指针
            return Obj.a;
        }
        this.sum = 0;
        this.getPrice = function(price){
            this.sum += price;
            return this.sum;
        };
        // 保存变量(关键)
        Obj.a = this;
    }
    var o1 = new Obj();
    var o2 = new Obj();
    o1 === o2             // 值 与 类型都相同(后端语言包含地址)
    

    3.函数 闭包 链式访问形式(命名空间)

    var Product = (function() {
        var unique;
        var sum = 0;
        // 判断函数
        function getInstance() {
            if(!unique) {
                unique = construct();
            };
            return unique;
        };
        // 保存单利对象的函数
        function construct() {
            return {
                getPrice: function() {},
                addCart: function() {}
                // 可以保存更多的方法及属性
            };
        };
    })();
    // 链式调用方法
    Product.getInstance().getPrice();
    

    二、工厂模式

    理论:通过使用工厂方法而不是new关键字及具体类,把所有实例化的代码都集中在一个位置。

    优点:有助于创建模块化的代码,消除对象之间的耦合。

    • 大型项目扩展影响小
    • 有助于提高项目的扩展性、灵活性
    • 封装性(封装创建过程)

    缺点:

    • 新增流水线,将不利于改造

    1.普通方式

        函数内部实例,并返回对象

    function Obj(name) {
        // 创建对象,并对对象拓展属性及方法
        var o = new Object();
        o.name = name;
        o.show = function() {
            alert(this.name);
        }
        // 将对象返回
        return o;
    };
    <!-- 创建需要的obj -->
    var doSome = Obj('wang');
    <!-- obj1 == obj2  // false -->
    

    2.零模式

    (1)工厂对象

    var Factory = function() {};  //构建工厂
    Factory.prototype = {         //工厂返回实例
        create:function(type){
            var product;
            switch(type) {
                case:'one':
                    product = new OnePro();
                    break;
                case:'two':
                    product = new TwoPro();
                    break;
            }
            return product;
        }
    };
    // 通过工厂返回相应的实例,而不是this的链式访问
    
    // 定义 products 分类
    var OnePro = function() {};   // 分类一
    OnePro.prototype = {
        name: 'one',
        getName:function(){
            return this.name;
        }
    } 
    var TwoPro = function() {};   // 分类二
    TwoPro.prototype = {
        name: 'two',
        getName:function(){
            return this.name;
        }
    }
    

    (2)工厂函数

    function factory(type) {
        var product;
        switch(type) {
            case:'one':
                product = new OnePro();
                break;
            case:'two':
                product = new TwoPro();
                break;
        };
        return product;
    };
    // 直接调用函数即可创建分类对象
    

    3.普通函数采用工厂模式实现new

    4.团队应用工厂模式

    (1)团队一、算法:

    var Price = {};    // 创建命名空间
    Price.vip = function() {    // 分类一
        this.dis = 0.3;
        this.getPrice = function(price) {
            return price * this.dis;
        }
    };
    Price.old = function() {    // 分类二
        this.dis = 0.5;
        this.getPrice = function(price) {
            return price * this.dis;
        }
    };
    Price.normal = function() {    // 分类三
        this.dis = 0.7;
        this.getPrice = function(price) {
            return price * this.dis;
        }
    };
    // 对新增分类有好处 直接添加即可
    

    (2)团队二、

    <!-- 生产不同的实例 不关心如何定义 -->
    Price.factory = function(type){
        return new Price[type]
    }
    

    (3)团队三、

    <!-- 使用对象的接口 不关心内部构造 -->
    var nomalPrice = Price.factory('normal');
    nomalPrice.getPrice(1000);
    

    三、策略模式[2]

    步骤:

    • 定义算法对象
      • 算法对象是为了解决频繁的扩展方法问题
    • 定义上下文
      • 上下文是为了框架的使用简洁化,不用关心算法细节
    • 使用

    优点:解耦合   模块化

    应用:

    • 保护核心系统
    • 屏蔽复杂对象
    • 延迟加载
      • 通过代理模式实现延迟加载
      • jqurey插件实现延迟加载

    1.策略模式

    <!-- 定义不同的计算函数 -->
    var vip = function(price) {
        return price * 0.3;  //执行算法代码
    };
    var old = function(price) {
        return price * 0.5;  //执行算法代码
    };
    var nomal = function(price) {
        return price * 0.7;  //执行算法代码
    };
    // 定义调用函数部分(定义上下文)
    var calculate = function(fn,price){
        return fn(price);
    };
    // 使用部分 
    var price = calculate(vip,1000);
    

    2.类反射方式

    <!-- 定义对象  存放各 类 的计算方法 -->
    var class = {
        "vip":function(price) {
            return price * 0.3;  //执行算法代码
        },
        "old":function(price) {
            return price * 0.5;  //执行算法代码
        },
        "nomal":function(price) {
            return price * 0.7;  //执行算法代码
        }
    };
    // 全局污染减少 
    var calculate = function(leval,price){
        // 反射机制
        return class[leval](price);
    };
    // 使用部分 
    var price = calculate("vip",1000);
    

    四、观察者模式(Observer):双向绑定的本质

    理论: 又称作:表-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-收听者(Source/Listener)模式、从属者(Dependents)模式、

    • 注册:
      • dom事件入队列(存入数组)
    • 监听:
      • 执行事件
    • 响应:
      • 执行回调函数

           1.观察者模式其实就是实现异步编程,javascript本身就是支持异步编程的语言。这是它的强大之处。
           2.观察者模式是利用函数回调来实现异步编程,当事件触发时,所有订阅者都会受到消息,并调用对应的处理函数,而不用实时监测,这显然在某些情况下,极大的提高了cpu的利用率。
           3.自定义事件就是异步编程的实际运用,让你可以将操作代码在你想要执行的时候去执行(触发事件),而不是传统的从上到下执行,增加了代码灵活性。并且,减少 了代码冗余,同样的操作,只需要触发同样的事件就行了,不需要再写一遍。

    优点:

    • 支持简单的广播通信,自动通知所有已经订阅过的对象
    • 页面载入后目标对象很容易与观察者存在一种动态关联,增加了灵活性
    • 目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用(高内聚,低耦合)

    缺点:

    扩充----事件轮询(Event Loop)[^3]
    [^3]:指的是计算机系统的一种运行机制。(JavaScript语言就采用这种机制,来解决单线程运行带来的一些问题。);主线程从“任务队列”中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件轮询)

    什么是进程:
            一般情况下,一个进程一次只能执行一个任务。如果有很多任务需要执行,不外乎三种解决方法。        (1)排队:因为一个进程一次只能执行一个任务,只好等前面的任务执行完了,再执行后面的任务。        (2)新建进程:使用fork命令,为每个任务新建一个进程。        (3)新建线程:因为进程太耗费资源,所以如今的程序往往允许一个进程包含多个线程,由线程去完成任务。
    >

    五、代理模式

    理论:代理模式就是用一个类来代替另一个类来执行方法功能

    优点:

    缺点:

    六、装饰者模式

    理论:

    优点:

    缺点:


    1. 如果一个函数接收的参数为或返回的值为函数,那么我们可以将这个函数称为高阶函数。 ↩︎

    2. (1)工厂模式解决了多种判断不需要if语句的问题,当新增属性或方法时,只需要从新定义一个对象即可,原有代码无需修改。
      (2)策略模式和工厂模式类似,只不过策略模式解决的是算法家族问题而不是对象实例问题。 ↩︎

  • 相关阅读:
    mock 数据模拟
    利用css绘制三角形,半圆等形状
    页面底部固定
    Form Data格式传参
    element 页面显示效果及需要注意的点
    vue 组件加载顺序
    vue-router 导航钩子
    vue 总结
    前端开发的碎碎念
    值匹配的方式
  • 原文地址:https://www.cnblogs.com/jwen/p/5416365.html
Copyright © 2011-2022 走看看