设计模式-js面向对象

175 阅读3分钟

编程语言分类

编程语言按照数据类型可以分成两类:静态类型语言和动态类型语言

  • 静态类型语言
    • 定义:编译时便已确定变量的类型
    • 优点:在编译时可以发现类型不匹配的错误,编辑器可以帮我们提前避免程序在运行期间有可能发生的一些错误。在程序中明确规定了数据类型,编译器还可以针对这些信息对程序做一些优化,提高程序执行速度。
    • 缺点:迫使程序员依照强契约来编写程序。类型的声明也会增加更多的代码,在编写过程中,也会让程序员的精力从思考业务逻辑上分散开来
  • 动态类型语言
    • 定义:变量类型要到程序原型时,被赋予某个值之后,才会具有某种类型
    • 优点:编写代码少,更加简洁,开发者更专注于逻辑表达。
    • 缺点:无法保证变量的类型,从而在程序的运行期间有可能发生跟类型相关的错误

多态

同一操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果,换句话说,给不同的对象发送同一个消息的时候,这些对象会根据这个消息分别给出不同的反馈。最根本的作用是把过程化的条件分支语句转化为对象的多态性,从而消除这些条件分支语句。

鸭与鸡的故事

makeSound方法里面传入不同的对象,console.log得到不同的返回值。这就是多态的具体表现,不需要在makeSound做if-else类型判断。

<template>
  <div>
    <button @click="animalSound.makeSound(duck)">鸭子</button>
    <button @click="animalSound.makeSound(chicken)"></button>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { AnimalSound, Animal } from '@/utils/polyFac';
export default defineComponent({
  setup() {
    return {
      animalSound: new AnimalSound(),
      chicken: new Animal('gegege'),
      duck: new Animal('gagaga'),
    }
  },
})
</script>

// polyFac.js
export class AnimalSound {
  makeSound(animal) {
    animal.makSound()
  }
}
export class Animal {
  constructor(props) {
    this.sound = props;
  }
  makSound() {
    console.log(this.sound);
  }
}

封装

封装的目的是将信息隐藏,狭义上的封装指的是封装数据和封装实现。广义上来说还包含封装类型和封装变化。

封装数据
const object = (function() {
  var _name = 'test'; // 私有变量private
  return {
    getName() { //公开变量 public
      return _name
    }
  }
})()
console.log(object.getName()); // test
console.log(object._name); // undefined
封装实现
// $$each封装内部循环实现细节,只要对外接口没有变化,用户就不用关心内部实现的改变
Object.prototype.$$each = function(cb: Function){
for (const key in this) {
  if (Object.prototype.hasOwnProperty.call(this, key)) {
    cb(this[key])
  }
}
};
const obj = {a: 1, b: 2};
obj.$$each((val: any) => console.log(val)) // 输出1、2
封装类型
  • 封装类型是静态类型语言中一种重要的封装方式,一般来说是通过抽象类和接口来进行额,但是在JS中没有相关支持,所以对于JS的设计模式来说,是不需要过分区分类型的。
封装变化
  • 从设计模式的角度出发,封装更重要体现在封装变化,设计模式基本上可以被划分为创建型模式结构型模式行为型模式
  • 通过封装变化的方式,将系统中稳定不变的部分和容易变化的部分分隔开来,从而最大程度的保证程序的稳定性和扩展性。这些后续会深入学习。