面向对象
继承:子类继承父类
封装:数据的权限和保密
多态:同一接口不同实现
// 父类class People {constructor(name, age) {this.name = namethis.age = age}eat() {alert(`${this.name} eat something`)}speak() {alert(`${this.name}: age ${this.age}`)}}// 子类继承父类class Student extends People {constructor(name, age, number){super(name, age)this.number = number}study() {alert(`${this.name} study`)}}// 实例let xiaoming = new Student('xiaoming', 10, 'A1')xiaoming.study()xiaoming.eat()let wangxin = new Student('wangxin', 10, 'A2')wangxin.study()wangxin.speak()
继承
People是父类,公共的,不仅仅服务于Student
继承可将公共方法抽离出来,提高复用,减少冗余
封装
(ES6尚不支持,TS支持)
定义属性关键字:
public: 完全开放;前面如果不写关键字,那么默认是public
protected: 对子类开放
private: 对自己开放
// 父类class People {nameageprotected weight // 对子类开放constructor(name, age) {this.name = namethis.age = agethis.weight = 120}eat() {alert(`${this.name} eat something`)}speak() {alert(`${this.name}: age ${this.age}`)}}// 子类继承父类class Student extends People {numberprivate girlFriendconstructor(name, age, number){super(name, age)this.number = numberthis.girlfriend = 'lu'}study() {alert(`${this.name} study`)}getWeight() {alert(`weight: ${this.weight}`)}}// 实例let xiaoming = new Student('xiaoming', 10, 'A1')xiaoming.study()xiaoming.eat()xiaoming.getWeight()xiaoming.girlFriend // 编译时会报错,直接会编译不通过!!!let wangxin = new Student('wangxin', 10, 'A2')wangxin.study()wangxin.speak()
减少耦合,不该外露的不外露
利于数据、接口的权限管理
ES6 不支持,一般认为以_开头的属性是 private
多态
同一个接口,不同表现
JS应用极少
需要结合java等语言的接口、重写、重载等功能
// 父类class People {constructor(name, age) {this.name = namethis.age = agethis.weight = 120}saySomething() {}}class A extends People {constructor(name) {super(name)}saySomething() {alert(`I am A : ${this.name}`)}}class B extends People {constructor(name) {super(name)}saySomething() {alert(`I am B : ${this.name}`)}}let a = new A('a')a.saySomething()let b = new B('b')b.saySomething()
保持子类的开放性和灵活性
面向接口编程
JS引用极少,了解即可
jQuery 应用举例
jQuery是一个class
$(‘p’)是jQuery的一个实例
class jQuery {constructor(selector) {let slice = Array.prototype.slicelet dom = slice.call(document.querySelectorAll(selector))let len = len ? dom.length : 0for (let i = 0; i < len; i++) {this[i] = dom[i]}this.length = lenthis.selector = selector || ''}append(node) {// ...}addClass(name) {// ...}html(data) {// ...}// ...}window.$ = function(selector) {// 工厂模式return new jQuery(selector)}// 测试代码var $p = $('p')console.log($p)console.log($p.addClass)
为何使用面向对象?
程序执行:顺序、判断、循环 ———— 结构化
面向对象 ———— 数据结构化
对于计算机,结构化的才是最简单的
编程:简单 & 抽象
UML 类图
Unified Modeling Language : 统一建模语言
UML包含很多种图,本章相关的是类图
关系
泛化:继承;空箭头
关联:引用: People 引用 House;实心箭头
演示,代码和类图的结合
MS Office Visio
// 父类class People {constructor(name, house) {this.name = namethis.house = house}saySomething() {}}class A extends People {constructor(name, house) {super(name, house)}saySomething() {alert(`I am A : ${this.name}`)}}class B extends People {constructor(name, house) {super(name, house)}saySomething() {alert(`I am B : ${this.name}`)}}class House {constructor(city) {this.city = city}showCity() {alert(`house in : ${this.name}`)}}let ahouse = new House('beijing')let a = new A('a', ahouse)a.saySomething()let b = new B('b')b.saySomething()
类图
类名
所有的属性:public 属性名A:类型
所有的方法:public 方法名A(参数1,参数2):返回值类型
‘+’: public
‘#’: protected
‘-‘: private
设计原则
即按照哪一种思路或者标准来实现功能
功能相同,可以有不同设计方案来实现
伴随着需求增加,设计的作用才能体现出来
《LINUX/UNIX设计哲学》
小即是美
让每个程序只做好一件事
快速建立原型
舍弃高效率而取可移植性(效率会因为硬件的升级而被抹平)
采用纯文本来存储数据
充分利用软件的杠杆效应(软件复用)
使用shell脚本来提高杠杆效应和可移植性
避免强制性的用户界面
让每个程序都成为过滤器
小准则:
允许用户定制环境
尽量使操作系统内核小而轻量化
使用小写字母并尽量简写
沉默是金
各部分之和大于整体
寻求90%的解决方案
ls | grep *.json | grep 'package'
5大设计原则
Single: 单一职责原则
一个程序只做好一件事
如果功能过于复杂
Open: 开放封闭原则
对扩展开放,对修改封闭
增加需求时,拓展新代码,而非修改已有代码
这是软件设计的终极目标
L: 李氏置换原则
子类能覆盖父类
父类能出现的地方子类就能出现
JS中使用较少(弱类型 & 继承使用较少)
Interface: 接口独立原则
保持接口的单一独立,避免出现“胖接口”
JS中没有接口(TS例外),使用较少
类似于单一职责原则,这里更关注接口
Dependence: 依赖倒置原则
面向接口编程,依赖于抽象而不依赖于具体
使用方只关注接口而不关注具体类的实现
JS中使用较少(没有接口 & 弱类型)
function loadImg(src) {return new Promise((resolve, reject) => {let img = document.createElement('img')img.onload = () => {resolve(img)}img.onerror = () => {reject('图片加载失败')}img.src = src})}let src = './img.png'let result = loadImg(src)result.then((img) => {alert(`width: ${img.width}`)return img}).then((img) => {alert(`height: ${img.height}`)}).catch((err) => {console.log(err)})
从设计到模式
设计:指导思想
模式:结合日常开发总结出固定的模板
23种设计模式
创建型
组合型
行为型
面试题
打车时,可以打专车或者快车;
任何车都有车牌号和名称;
不同车价格不同,快车1元/km,专车2元/km;
行程开始时,显示车辆信息;
行程结束时,显示打车金额(假定行程就5km)。
class Car {constructor(number, name) {this.number = numberthis.name = name}}class KuaiChe extends Car {constructor(number, name) {super(number, name)this.price = 1}}class ZhuanChe extends Car {constructor(number, name) {super(number, name)this.price = 2}}class Trip {constructor(car) {this.car = car}start() {console.log(`行程开始 名称:${this.car.name} 车牌号:${this.car.number}`)}end() {console.log(`行程结束 价格:${this.car.price} * 5`)}}let car = new KuaiChe(100, '桑塔纳')let trip = new Trip(car)trip.start()trip.end()
某停车场,分3层,每层100车位;
每个车位都能监控到车辆的驶入和离开;
车辆进入前,显示每层的空余车位数量;
车辆进入时,摄像头可识别车牌号和时间;
车辆出来时,出口显示器显示车牌号和停车时长。
设计模式
优先级:创建型 | 结构型 | 行为型
结合核心技术
结合框架应用
综合示例
设计方案
代码演示
设计模式对应(7种)
