资讯专栏INFORMATION COLUMN

javascript设计模式与开发实践(一)- 多态

wthee / 3366人阅读

摘要:当我们对一些函数发出调用的消息时,这些函数会返回不同的执行结果,这是多态性的一种体现,也是很多设计模式在中可以用高阶函数来代替实现的原因。

PS:上一篇文章发表之后,很多朋友关注了本人的思否和掘金的博客,虽然关注的朋友还有有限,但足够让我把自己在技术上的问题积累分享给大家,也希望大家能够喜欢,同时能动一动手指,给一颗心(赞),博主会持续更新下去 多态

本文是《javascript设计模式与开发实践》一书学习笔记,因书中所表述的概念简单明了,故将整本书的笔记奉上,全部文章大概在20篇左右,还请朋友们持续关注

动态语言类型

编程语言按照数据类型大体可以分为两类,一类是静态类型语言,另一类是动态类型语言

静态类型语言,声明任何变量或者形参都需要指定类型,例如java语言。
动态类型语言,声明任何变量或者形参都不需要指定类型,javascript就是动态类型语言。

所谓动态,可以多层面的理解,首先,声明变量不需要指定类型,其次,在多态思想下,java中需要利用父类实现多态,而javascript就不需要,本身自带多态属性。

多态

熟悉java的朋友知道,java三大特征之一就有多态,多态给java带来了很大的灵活性,很多设计模式也是通过多态来实现,java中的多态涉及到向上转型和向下转型,而javascript(以下简称js)的"多态"就相对来说容易实现

我们来看一段“多态”的js代码

var makeSound = function(an) {
    if(an instanceof Duck) {
        console.log("嘎嘎嘎");
    } else if(an instanceof Dog) {
        console.log("汪汪汪");
    }
}

var Dog = function(){};
var Duck = function(){};

makeSound(new Dog());
makeSound(new Duck());

这段代码确实体现了“多态性”,当我们分别向鸭和鸡发出“叫唤”的消息时,它们根据此 消息作出了各自不同的反应,但是这样写会有一个弊端,当更多的类型出现时,我们要不断的修改makeSound函数,后期makeSound函数也会变得十分巨大,这不符合良好代码设计的规范,多态背后的思想是将“做什么”和“谁去做以及怎样去做”分离开来,也就是将“不变的事 物”与 “可能改变的事物”分离开来。在这个故事中,动物都会叫,这是不变的,但是不同类 型的动物具体怎么叫是可变的。把不变的部分隔离出来,把可变的部分封装起来,这给予了我们 扩展程序的能力,程序看起来是可生长的,也是符合开放—封闭原则的,相对于修改代码来说, 仅仅增加代码就能完成同样的功能,这显然优雅和安全得多

首先,我们把makeSound函数修改一下:

var makeSound = function(an) {
    an.speak();
}

这段代码传入一个对象,然后调用对象的speak函数

var Duck = function(){}
Duck.prototype.sound = function(){
    console.log( "嘎嘎嘎" );
};
var Chicken = function(){}
Chicken.prototype.sound = function(){
    console.log( "咯咯咯" );
};
makeSound( new Duck() ); // 嘎嘎嘎
makeSound( new Chicken() );

现在我们向鸭和鸡都发出“叫唤”的消息,它们接到消息后分别作出了不同的反应。如果有 一天动物世界里又增加了一只狗,这时候只要简单地追加一些代码就可以了,而不用改动以前的 makeSound 函数

类型检查和多态

现在,我们来进一步了解多态,之前说到,java的多态需要利用继承来实现,我们现在把动物的例子换成java代码

public class Duck {
    public void speak(){
        System.out.println( "嘎嘎嘎" );
    }
}

public class Dog {
    public void speak(){
        System.out.println( "汪汪汪" );
    }
}

public class AnimalSpeak{
    public void makeSound(Duck duck){
        duck.speak();
    }
}

public static void main(String args[]){
    AnimalSpeak an = new AnimalSpeak();
    Duck duck = new Duck();
    an.makeSound(duck); // 输出:嘎嘎嘎
}

现在鸭子已经顺利叫出来了,但是我们想让狗也叫,发现不太容易实现,因为makeSound函数中,形参是Duck类型,传入Dog类型一定会报错,这个时候继承就出现了,java设计思路是我先创建一个父类,具体传入的类型由子类决定,但是makeSound函数中的形参确是父类类型,实现如下:

public abstract class Animal{
    abstract void speak(); // 抽象方法
}

public class Duck extends Animal {
    public void speak(){ // 覆写父类中的抽象方法
        System.out.println( "嘎嘎嘎" );
    }
}

public class Dog extends Animal {
    public void speak(){ // 覆写父类中的抽象方法
        System.out.println( "汪汪汪" );
    }
}

public class AnimalSpeak{
    public void makeSound(Animal an){
        an.speak();
    }
}

public static void main(String args[]){
    AnimalSpeak an = new AnimalSpeak();
    Animal duck = new Duck();
    Animal dog = new Dog();
    an.makeSound(duck); // 输出:嘎嘎嘎
    an.makeSound(dog); // 输出:汪汪汪
}
js中的多态

JavaScript 对象的多态性是与生俱来的,为什么这么说? 仔细看看这两个函数:

public void makeSound(Animal an){
    an.speak();
}

function(an) {
    an.speak();
}

js和java中的函数的形参是不同的,java定死了传入的类型,而js是动态的,js随便可以传入任何类型,所以,我们之前说js是动态类型语言,在 JavaScript 这种将函数作为一等对象的语言中,函数本身也是对象,函数用来封装行为并 且能够被四处传递。当我们对一些函数发出“调用”的消息时,这些函数会返回不同的执行结 果,这是“多态性”的一种体现,也是很多设计模式在 JavaScript 中可以用高阶函数来代替实现的原因。

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

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

相关文章

  • JavaScript设计模式开发实践 | 01 - 面向对象的JavaScript

    摘要:在中,并没有对抽象类和接口的支持。例如,当对象需要对象的能力时,可以有选择地把对象的构造器的原型指向对象,从而达到继承的效果。本节内容为设计模式与开发实践第一章笔记。 动态类型语言 编程语言按数据类型大体可以分为两类:静态类型语言与动态类型语言。 静态类型语言在编译时已确定变量类型,动态类型语言的变量类型要到程序运行时,待变量被赋值后,才具有某种类型。 而JavaScript是一门典型...

    suxier 评论0 收藏0
  • 学习设计模式前需要知道的事情

    摘要:为什么要学习设计模式做事情之前问个为什么总是好的。设计模式的使用方法关于使用方式,像我这种初学者最容易犯的错误就是生搬硬套,但是模仿本来也是学习的一个过程,最重要的事情是在模仿中要学会思考。 为什么要学习设计模式? 做事情之前问个为什么总是好的。关于设计模式的好坏,我在知乎上也看过一些讨论,有知友对其提出过一些疑问,里面有一些关于设计模式的观点: 设计模式有何不妥,所谓的荼毒体现在哪...

    kviccn 评论0 收藏0
  • javascript面向对象之“多态

    摘要:之前,本质上不能算是一门面向对象的编程语言,因为它对于封装继承多态这些面向对象语言的特点并没有在语言层面上提供原生的支持。所以在中出现了等关键字,解决了面向对象中出现了问题。 ES6之前,javascript本质上不能算是一门面向对象的编程语言,因为它对于封装、继承、多态这些面向对象语言的特点并没有在语言层面上提供原生的支持。但是,它引入了原型(prototype)的概念,可以让我们以...

    JerryWangSAP 评论0 收藏0
  • JavaScript多态适配器模式思考

    摘要:下面是我仿照适配器模式改进的谷歌地图百度地图适配器参数配置适配器地图只关注发出显示地图而不关注具体用哪种地图当增加了搜搜地图,我们需要添加搜搜地图的方法以及修改适配器地图参数而不需要对函数进行修改搜搜地图 不多说先上一段代码(转载自《JavaScript设计模式与开发实践》) //谷歌地图show方法 var googleMap = { ...

    binta 评论0 收藏0
  • JavaScript设计模式开发实践》 —— <阅读小札·>

    摘要:阅读小札一阅读前自大学课上,就开始接触设计模式,但对设计模式却鲜有研究与实践。第二部分是核心部分,由浅到深讲解个设计模式。设计模式遵循的原则所有设计模式罪训的一条原则就是找出程序中变化的地方,并将变化封装起来。 阅读小札 · 阅读前 自大学Java课上,就开始接触设计模式,但对设计模式却鲜有研究与实践。最近向公司反映和游说技术提升,得以获得公司提供购书机会,借此认真学习前端学习之路的...

    Yangder 评论0 收藏0

发表评论

0条评论

wthee

|高级讲师

TA的文章

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