多态和封装

摘自《JavaScript设计模式与开发实践》

多态

同一操作作用于不同的对象上面可以产生不同的解释和执行不同的结果。换句话说,给不同的对象发送同一个消息的时候,这些对象会根据这个消息分别给出不同的反馈。

function makeSound (animal) {
  animal.sound()
}
function Duck() {
  
}
Dack.prototype.sound = function() {
  console.log('嘎嘎嘎')
}

function Children() {

}
Children.prototype.sound = function() {
  console.log('咯咯咯')
}

makeSound(new Duck()) 
makeSound(new Children())

多态把“做什么”和“谁去做”分离开来。我们只需要知道做什么,但是具体怎么做,这我们不用管。上面栗子中,我们只需要让动物出声,但是是发出“嘎嘎嘎”还是“咯咯咯”,我们不需要理会。

利用对象的多态性,对象在做什么并不是临时决定的,而是事先已经约定和安排的,这个对象应该做什么,已经成了对象的一个方法,每个对象负责自己的行为。

多态的作用

Martin Fowler在《重构:改善既有代码的设计》里写到:多态的最根本好处在于,你不必再向对象询问“你是什么类型”而后根据得到的答案调用对象的某个行为——你只管调用该行为就是了,其他的一切多态机制都会为你安排妥当。

换句话说,多态最根本的作用就是通过把过程化的条件分支语句转化为对象的多态性,从而消除这些条件分支语句。Martin Fowler的话可以用下面这个例子很好地诠释:

在电影的拍摄现场,当导演喊出“action”时,主角开始背台词,照明师负责打灯光,后面的群众演员假装中枪倒地,道具师往镜头里撒上雪花。在得到同一个消息时,每个对象都知道自己应该做什么。如果不利用对象的多态性,而是用面向过程的方式来编写这一段代码,那么相当于在电影开始拍摄之后,导演每次都要走到每个人的面前,确认它们的职业分工(类型),然后告诉他们要做什么。如果映射到程序中,那么程序中将充斥着条件分支语句。

利用对象的多态性,导演在发布消息时,就不必考虑各个对象接到消息后应该做什么。对象应该做什么并不是临时决定的,而是已经事先约定和排练完毕的。每个对象应该做什么,已经成为了该对象的一个方法,被安装在对象的内部,每个对象负责它们自己的行为。所以这些对象可以根据同一个消息,有条不紊地分别进行各自的工作。将行为分布在各个对象中,并让这些对象各自负责自己的行为,这正是面向对象设计的优点。再看一个现实开发中遇到的例子,这个例子的思想和动物叫声的故事非常相似。

封装

封装的目的是将信息隐藏。

封装数据

在javascript中并没有提供对 public、private、protected 等关键字的支持,我们只能依赖变量的作用域来实现封装的特性。

var myObject = (function() {
  var __name = 'yy'  // 私有的变量
  return {
    getName: function() {
      return __name // 公开的方法
    }
  }
})()

封装实现

封装的目的是将信息隐藏,封装应该被视为“任何形式的封装”,也就是说,封装不仅仅是隐藏数据,还包括隐藏实现细节、设计细节以及隐藏对象的类型等。从封装实现细节来讲,封装使得对象内部的变化对其他对象而言是透明的,也就是不可见的。对象对它自己的行为负责。其他对象或者用户都不关心它的内部实现。

封装使得对象之间的耦合变松散,对象之间只通过暴露的 API接口来通信。当我们修改一个对象时,可以随意地修改它的内部实现,只要对外的接口没有变化,就不会影响到程序的其他功能。

封装类型

封装类型是静态类型语言中一种重要的封装方式。一般而言,封装类型是通过抽象类和接口来进行的 。把对象的真正类型隐藏在抽象类或者接口之后,相比对象的类型,客户更关心对象的行为。在许多静态语言的设计模式中,想方设法地去隐藏对象的类型,也是促使这些模式诞生的原因之一。比如工厂方法模式、组合模式等。

当然在 JavaScript中,并没有对抽象类和接口的支持。JavaScript本身也是一门类型模糊的语言。在封装类型方面,JavaScript没有能力,也没有必要做得更多。对于 JavaScript的设计模式实现来说,不区分类型是一种失色,也可以说是一种解脱。在后面章节的学习中,我们可以慢慢了解这一点。

封装变化

要创建一个对象,是一种抽象的行为,而具体创建什么对象是可以变化,通过封装变化的方式,把系统中稳定不变的部分和容易变化的部分分隔开来,我们只需要替换容易变化的那一部分。

你可能感兴趣的:(多态和封装)