JavaScript设计模式之工厂模式和构造器模式


Posted in Javascript onFebruary 11, 2015

什么是模式

前阵子准备期末考试,劳神又伤身的,实在闲不得空来更新文章,今天和大家说说javascript中的设计模式。

首先呢,我们需要知道的是:模式是一种可复用的解决方案,而反模式呢就是针对某个问题的不良解决方案。

js反模式常见例子

1.向setTimeout和setInterval传递字符串,而不是函数,这会触发eval()的内部使用。
2.在全局上下文中定义大量的变量污染全局命名空间
3.修改Object类的原型
4.以内联形式使用js,嵌入在HTML文件中的js代码是无法包含在外部单元测试工具中的。
5.滥用document.write,如果在页面加载完成后执行docume.write,它会重写我们所在的页面,可以使用document.creatElement代替的话就尽量不用docume.write。

设计模式的类别

创建型设计模式

创建型设计模式专注于处理对象创建机制,以适合给定情况的方式来创建对象。属于这个类别的属性包括:

Constructor构造器、Factory工厂、Abstract抽象、Prototype原型、Singleton单例和Builder生成器

结构型设计模式

结构型模式与对象组合有关,通常可以用于找出在不同对象之间建立关系的简单方法。
属于这个类别的模式包括:

Decorator装饰者、Facade外观、Flyweight享元、Adapter适配器和Proxy代理

行为设计模式

行为模式专注于改善或简化系统中不同对象之间的通信。

行为模式包括:

Iterator迭代器、Mediator中介者、Observer观察者和Visitor访问者

Factory(工厂)模式

为了解决多个类似对象声明的问题,我们可以使用一种叫做 工厂模式的方法,这种方法 就是为了解决实例化对象产生大量重复的问题。

<script type="text/javascript">

    function createObject(name,age,profession){//集中实例化的函数

        var obj = new Object();

        obj.name = name;

        obj.age = age;

        obj.profession = profession;

        obj.move = function () {

            return this.name + ' at ' + this.age + ' engaged in ' + this.profession;

        };

        return obj;

    }

    var test1 = createObject('trigkit4',22,'programmer');//第一个实例

    var test2 = createObject('mike',25,'engineer');//第二个实例

    alert(test1.move());

    alert(test2.move());

</script>

工厂模式的分类

工厂模式分为简单工厂、抽象工厂和智能工厂,工厂模式不显示地要求使用一个构造函数。

简单工厂模式:使用一个类(通常为单体)来生成实例。
复杂工厂模式:使用子类来决定一个成员变量应该是哪个具体的类的实例。

工厂模式之利

主要好处就是可以消除对象间的耦合,通过使用工程方法而不是new关键字。将所有实例化的代码集中在一个位置防止代码重复。
工厂模式之弊

大多数类最好使用new关键字和构造函数,可以让代码更加简单易读。而不必去查看工厂方法来知道。   
工厂模式解决了重复实例化的问题 ,但还有一个问题,那就是识别问题,因为根本无法 搞清楚他们到底是哪个对象的实例。

alert(typeof test1); //Object 

alert(test1 instanceof Object); //true

何时使用工厂模式?

Factory模式主要在以下场景使用:

1.当对象或组件涉及高复杂性时
2.当需要根据所在的不同环境轻松生成对象的不同实例时
3.当处理很多共享相同属性的小型对象或组件时

Constructor(构造器)模式

ECMAScript 中可以采用构造函数(构造方法)可用来创建特定的对象。 该模式正好可以解决以上的工厂模式无法识别对象实例的问题。

<script type="text/javascript">

    function Car(model,year,miles){//构造函数模式

        this.model = model;

        this.year = year;

        this.miles = miles;

        this.run = function () {

            return this.model + " has done " + this.miles + "miles";

        }

    }

    var Benz = new Car('Benz',2014,20000);

    var BMW = new Car("BMW",2013,12000);

    alert(Benz instanceof Car); //很清晰的识别他从属于 Car,true
    console.log(Benz.run());

    console.log(BMW.run());

</script>

使用构造函数的方法 ,即解决了重复实例化的问题 ,又解决了对象识别的问题,该模式与工厂模式的不同之处在于:

1.构造函数方法没有显示的创建对象 (new Object());
2.直接将属性和方法赋值给 this 对象;
3.没有 renturn 语句。

构造函数的方法有一些规范:

1.函数名和实例化构造名相同且大写, (PS:非强制,但这么写有助于区分构造函数和 普通函数);
2.通过构造函数创建对象,必须使用 new 运算符。 
既然通过构造函数可以创建对象,那么这个对象是哪里来的, new Object()在什么地方执行了?执行的过程如下:

1.当使用了构造函数,并且 new 构造函数(),那么就后台执行了 new Object();
2.将构造函数的作用域给新对象 ,(即 new Object()创建出的对象),而函数体内的 this 就 代表 new Object()出来的对象。
3.执行构造函数内的代码;
4.返回新对象(后台直接返回)。

带原型的Constructor(构造器)

js中有一个名为prototype的属性。调用js构造器创建一个对象后,新对象就会具有构造器原型的所有属性。通过这种方式,可以创建多个Car对象,并访问相同的原型。

   <script type="text/javascript">

        function Car(model,year,miles) {

            this.model = model;

            this.year = year;

            this.miles = miles;

        }

        Car.prototype.run = function () {

            return this.model + " has done " + this.miles + " miles ";
        };

        var Benz = new Car('S350',2010,20000);

        var Ford = new Car('Ford',2012,12000);
        console.log(Benz.run());//"S350 has done 20000 miles "

        console.log(Ford.run());

    </script>

现在run()的单一实例就能够在所有Car对象之间共享。
Javascript 相关文章推荐
图片上传即时显示缩略图的js代码
May 27 Javascript
javascript Onunload与Onbeforeunload使用小结
Dec 31 Javascript
JQuery中绑定事件(bind())和移除事件(unbind())
Feb 27 Javascript
jQuery使用before()和after()在元素前后添加内容的方法
Mar 26 Javascript
基于AngularJS+HTML+Groovy实现登录功能
Feb 17 Javascript
webix+springmvc session超时跳转登录页面
Oct 30 Javascript
javascript中BOM基础知识总结
Feb 14 Javascript
jQuery EasyUI Panel面板组件使用详解
Feb 28 Javascript
AngularJS $http模块POST请求实现
Apr 08 Javascript
微信小程序页面传值实例分析
Apr 19 Javascript
微信小程序 开发之全局配置
May 05 Javascript
Vue.js@2.6.10更新内置错误处机制Fundebug同步支持相应错误监控
May 13 Javascript
js实现可兼容IE、FF、Chrome、Opera及Safari的音乐播放器
Feb 11 #Javascript
45个JavaScript编程注意事项、技巧大全
Feb 11 #Javascript
JS实现判断碰撞的方法
Feb 11 #Javascript
javascript异步编程代码书写规范Promise学习笔记
Feb 11 #Javascript
jquery实现动态操作select选中
Feb 11 #Javascript
JS操作HTML自定义属性的方法
Feb 10 #Javascript
jQuery制作仿Mac Lion OS滚动条效果
Feb 10 #Javascript
You might like
PHP使用pcntl_fork实现多进程下载图片的方法
2014/12/16 PHP
JavaScript中将一个值转换为字符串的方法分析[译]
2012/09/21 Javascript
jquery实现弹出窗口效果的实例代码
2013/11/28 Javascript
使用js判断控件是否获得焦点
2014/01/03 Javascript
JavaScript实现鼠标滑过图片变换效果的方法
2015/04/16 Javascript
jQuery自动添加表单项的方法
2015/07/13 Javascript
JS实现图片平面旋转的方法
2016/03/01 Javascript
浅谈jquery的map()和each()方法
2016/06/12 Javascript
AngularJS包括详解及示例代码
2016/08/17 Javascript
javascript中的深复制详解及实例分析
2016/12/29 Javascript
js时间戳和c#时间戳互转方法(推荐)
2017/02/15 Javascript
解决给dom元素绑定click等事件无效问题的方法
2017/02/17 Javascript
JS实现电商放大镜效果
2017/08/24 Javascript
Javascript实现动态时钟效果
2018/11/17 Javascript
vue.js多页面开发环境搭建过程
2019/04/24 Javascript
详解Vue中的基本语法和常用指令
2019/07/23 Javascript
微信小程序如何修改radio和checkbox的默认样式和图标
2019/07/24 Javascript
Layui 数据表格批量删除和多条件搜索的实例
2019/09/04 Javascript
[50:17]Newbee vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
[04:32]玩具屠夫中文语音节选
2020/08/23 DOTA
Python迭代器定义与简单用法分析
2018/04/30 Python
对Python中class和instance以及self的用法详解
2019/06/26 Python
安装好Pycharm后如何配置Python解释器简易教程
2019/06/28 Python
详解Python中pyautogui库的最全使用方法
2020/04/01 Python
CSS中垂直居中的简单实现方法
2015/07/06 HTML / CSS
香港艺人陈冠希创办的潮流品牌:JUICESTORE
2021/03/04 全球购物
一套VC试题
2015/01/23 面试题
期末自我鉴定
2014/01/23 职场文书
大学生2014全国两会学习心得体会
2014/03/10 职场文书
保密承诺书范文
2014/03/27 职场文书
2014年廉洁自律承诺书
2014/05/26 职场文书
公安局副政委班子个人对照检查材料
2014/10/04 职场文书
小学重阳节活动总结
2015/03/24 职场文书
检察院起诉意见书
2015/05/20 职场文书
美容院管理规章制度
2015/08/05 职场文书
解决Git推送错误non-fast-forward的方法
2022/06/25 Servers