资讯专栏INFORMATION COLUMN

JavaScript设计模式第一弹-创建型设计模式

陈江龙 / 2458人阅读

摘要:前言接下来将会为大家介绍设计模式中的创建型设计模式,在此之前需要掌握一定的对象继承基础。但是如果是工厂方法模式的话,则只需要往工厂方法中添加基类则可以。

前言

接下来将会为大家介绍设计模式中的创建型设计模式,在此之前需要掌握一定的JavaScript对象继承基础。

简单工厂模式 先说说

什么是简单工厂模式:又叫静态工厂方法,由一个工厂对象决定创建某一种产品对象类的实例

看着定义有点懵,没关系。继续往下走

工厂函数

说明:简单来说,就是为了把多个相同类型的类集成到一个函数内,我们把这个函数叫做工厂函数

用途:使得其他人不用关注创建对象是基于哪个基类,直接用该工厂函数即可

代码

//定义小猫类
var Cat = function(){
    this.voice = "喵";
}
Cat.prototype.getVoice = function(){
    console.log(this.voice);
}

//定义小狗类
var Dog = function(){
    this.voice = "汪";
}
Dog.prototype.getVoice = function(){
    console.log(this.voice);
}

//动物工厂
var AnimalFactory = function(name) {
    switch(name){
        case "cat":
            return new Cat();
        case "dog":
            return new Dog();
    }
}

//创建实例
var hellokity = AnimalFactory("cat");
hellokity.getVoice();   //"喵"

当然,上面两种方法十分相似,于是还可以有下面的定义方式:

var createAnimal = function(name,voice) {
    var o = new Object(); 
    o.name = name;
    o.voice = voice;
    o.getVoice = function() {
        console.log(this.voice);
    }
    return o;
}
var hellokity = createAnimal("hellokity","喵");
hellokity.getVoice();   //"喵"

看似最后一种方法好像简便不少,但是实际上这两种定义方法是有区别的。

第一种方式所定义的实例对象是拥有父类的方法,也就是可以访问到原型链上面的属性和方法的。

第二种方式定义则是因为在内部新建了一个对象,那么父级对象什么的自然也就不存在了(当然这里不是指object)。

最后回顾

最后再次加深对简单工厂模式的印象吧

简单工厂模式:又叫静态工厂方法,由一个工厂对象决定创建某一种产品对象类的实例

工厂方法模式 先说说

什么是工厂方法模式:通过对产品类的抽象使其创建业务主要负责用于创建多类产品的实例

懵?没关系。继续往下走

安全模式类

用途:可以屏蔽使用该类的所造成的错误

例子

var Demo = function() {};
Demo.prototype.getName = function(){
    console.log("get success!")
}

var d = Demo();
d.getName();    //报错

//安全模式类
var Demo = function() {
    if(!(this instanceof Demo)){
        return new Demo
    }
};
Demo.prototype.getName = function(){
    console.log("get success!")
}

var d = Demo();
d.getName();    //"get success!"
工厂方法

实际上工厂方法和简单工厂模式区别在于:简单工厂模式如果需要增加类的话,那么它则需要改变两处地方,一处是工厂函数,一处是改变类。但是如果是工厂方法模式的话,则只需要往工厂方法中添加基类则可以。代码实现如下:

//安全模式创建的工厂类
var superHeroFatory = function(type,skill){
    if(this instanceof superHeroFatory){
        var s = new this[type](skill);
        return s
    }else{
        return new superHeroFatory(type,skill)
    }
}
superHeroFatory.prototype = {
    IronMan: function(skill){
        this.name = "Iron Man";
        this.skill = skill;
        this.getName = function(){
            console.log(this.name);
        }
        this.getSkill = function(){
            console.log(this.skill);
        }
    },
    CaptainAmerica: function(skill){
        this.name = "Captain America";
        this.skill = skill;
        this.getName = function(){
            console.log(this.name);
        }
        this.getSkill = function(){
            console.log(this.skill);
        }
    }
}

var captainAmerica = superHeroFatory("CaptainAmerica","shield");
captainAmerica.getName();   //"Captain America"
captainAmerica.getSkill();  //"shield"
最后回顾

这个工厂方法模式解决了创建多类对象所带来的麻烦,这样的工厂方法对象的方式也避免了使用者与对象类之间的耦合,用户不关心创建该对象的具体类,只需调用工厂方法即可。

抽象工厂模式 先说说

什么是抽象工厂模式:通过对类的工厂抽象使其业务用于对产品类簇的创建,而不负责创建其某一类产品的实例

看着定义有点懵,没关系。继续往下走

抽象类

概念:抽象类是一种声明但不能使用的类,使用就会报错。

用途:定义一个产品簇,并声明一些必备的方法,如果子类没有重写就会报错

例子:在java中可以简单定义,但是在js中的话暂时还没有这种抽象类的定义,于是我们可以用这种方式模仿抽象类:

var Car = function() {};
Car.prototype = {
    getPrice(){
        return new Error("抽象方法不可用")
    },
    getName(){
        return new Error("抽象方法不可用")
    }
}

于是乎,在对象实例化后调用这些函数就会报错。因为抽象类是没有具体实现的,它只用作继承的方式

抽象工厂模式

说明:为了更好的创建抽象类,于是将抽象类整合为一个抽象工厂

用途:用于创建抽象对象的一种方法

定义

var VehicleFactory = function(subType,superType){
    if(typeof VehicleFactory[superType] === "function"){
        // 缓存类
        function F() { };
        
        //继承父类属性和方法
        F.prototype = new VehicleFactory[superType]();
        
        //子类constructor指向子类
        subType.constructor = subType;
        
        //子类原型继承“父类”
        subType.prototype = new F();
    }else{
        throw new Error("未创建该抽象类")
    }
}

//小汽车抽象类 
VehicleFactory.Car = function(){
    this.type = "car";
}
VehicleFactory.Car.prototype = {
    getPrice(){
        return new Error("抽象方法不可用")
    },
    getName(){
        return new Error("抽象方法不可用")
    }
}

//大巴抽象类
VehicleFactory.Bus = function(){
    this.type = "bus";
}
VehicleFactory.Bus.prototype = {
    getPrice(){
        return new Error("抽象方法不可用")
    },
    getName(){
        return new Error("抽象方法不可用")
    }
}
抽象类的实现

啥也别说了,直接上码

var BMW = function(price,name){
    this.price = price;
    this.name = name;
}
VehicleFactory(BMW,"Car");
BMW.prototype.getName = function(){
    console.log(this.name);
}

var X2 = new BMW(200,"X2");
X2.getName();   //"X2"
X2.getPrice();  //报错,因为忘记定义这个方法了
最后回顾

最后再次感受一下定义吧

抽象工厂模式:通过对类的工厂抽象使其业务用于对产品类簇的创建,而不负责创建其某一类产品的实例

建造者模式 先说说

什么是建造者模式:将一个复杂对象的构建层与其表示层相互分离,同样的构建过程可采用不同的表示

与工厂模式差别

工厂模式主要是为了创建对象实例或者类簇(抽象工厂),关心的是最终创建的是什么,而对创建的过程并不关心

建造者模式在创建对象时要更复杂,它更多的关心创建对象的过程甚至于每个细节。或者说这种模式创建了一个复合对象

建造者模式

说明:关心创建对象的过程,对于创建的具体实现的细节也参与了干涉

用途:当需要我们创建对象不仅需要得到对象实例,还需对对象细化时,则可以使用建造者模式

代码

//创建类
var Human = function(props){
    this.name = props && props.name || "保密";
}
Human.prototype.getName = function(){
    console.log(this.name);
}

//名字类
var Name = function(name){
    var that = this;
    (function(name,that){
        that.wholeName = name;
        if(name.indexOf(" ") > -1){
            that.FirstName = name.slice(0,name.indexOf(" "));
            that.SecondName = name.slice(name.indexOf(" "));
        }
    })(name,that)
}


var Person = function(name){
    var _name = new Name(name);
    var _person = new Human({name:_name});
    return _person
}

var Miles = new Person("Miles Jiang");
Milse.getName();    //{wholeName: "Miles Jiang", FirstName: "Miles", SecondName: " Jiang"}
最后回顾

这种模式下,我们就可以关心到对象的创建过程。因此我们通常将创建对象模块化,这样使得被创建的类的每个模块都可以获得灵活的运用和高质量的复用

单例模式 先说说

什么是单例模式:又被称为单体模式,是只允许实例化一次的对象类。有时我们也用一个对象来规划一个命名空间,井井有条地管理对象上的属性与方法

命名空间

说明:用来约束每个人定义的变量

用途:防止共同开发时带来的变量名冲突

例子

var Miles = {
    getDom: function(id){
        return document.getElementById(id)
    }
}
最后回顾

为了梳理代码,使得代码有序整洁

后话

本文章是通过学习张荣铭所著的《JavaScript设计模式》所总结。希望大家看完文章可以学到东西,同时也推荐大家去看看这本设计模式,写得很不错。

成功不在一朝一夕,我们都需要努力

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108537.html

相关文章

  • JAVA笔记 - 收藏集 - 掘金

    摘要:动态代理个经纪人如何代理个明星掘金在代理模式女朋友这么漂亮,你缺经纪人吗中我们用宝强的例子介绍了静态代理模式的概念。掘金使用从头创建一个,这种方法比较简单。 动态代理:1 个经纪人如何代理 N 个明星 - Android - 掘金在 代理模式:女朋友这么漂亮,你缺经纪人吗? 中我们用宝强的例子介绍了静态代理模式的概念。 本来我的目的是通过大家耳熟能详的例子来加深理解,但是有些网友指责...

    kamushin233 评论0 收藏0
  • 老鸟学Javascript - 一弹

    摘要:顺带一提,跨域可以用解决。本文主要关注一些离散的,即学即用的知识点,和一些在日常编程中容易踩得坑。不做类型转换,所以如果比较对象的类型不一致,直接返回。当程序员给一个变量赋值为时,通常表示这个变量已经不用了。 原文:http://h01mes.com/veteran-new... 我仍然记得在一个ajax小项目踩到跨域问题(CORS)的坑,最后用Chrome插件解决。由此对Javasc...

    AlexTuan 评论0 收藏0
  • 小程序一弹

    摘要:前期准备微信小程序开发工具,以及网页的相关知识,本章知识了解微信小程序的基本使用。首先我们需要注册一个号。注册好后登陆,就可以进行开发了接着就是熟悉小程序的目录。大佬详细教程小程序的程序员变现指南之微信小程序真的零基础开发宝典 ...

    miracledan 评论0 收藏0
  • APP开放源码一弹《纳豆》

    摘要:纳豆外卖,预订座餐特点预订在家中公司,提前选择要去的餐厅,提前选好菜支付后,到店即可就餐外卖全城美食中餐快餐小吃等动动手指即可送到您手中。推荐经常为您推荐一些特色的美食豆圈分享你生活中的美食每刻。图片二维码扫描源码地址 2016年7月2日,这是一个风轻云淡的日子,DeviceOne平台的用户Star将自己经过一段时间研发的产品通过官方的渠道开源出来,这不仅是对自己设计的高度自信、更是想...

    wqj97 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<