Code前端首页关于Code前端联系我们

JavaScript 设计原则

terry 2年前 (2023-09-09) 阅读数 140 #Javascript
文章标签 JavaScript设计原则

面向对象

概念

// 类,即模版
class People {
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  eat() {}
  speak() {}
}

三要素

  • 继承,子类继承父类
// 父类
class People {
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  eat() {}
  speak() {}
}

// 子类继承父类
class Student extends People {
  constructor(name, age, number) {
    super(name, age)
    this.number = number
  }
  study() {}
}
  • 封装、数据权限和机密性
// 父类
class People {
  name
  age
  protected weight // 受保护的属性,只有自己或者子类可以访问
  constructor(name, age) {
    this.name = name
    this.age = age
    this.weight = 120
  }
  eat() {}
  speak() {}
}

// 子类 继承父类
class Student extends People {
  number
  private girlfriend
  constructor(name, age, number) {
    super(name, age)
    this.number = number
    this.girlfriend = 'xiaoli'
  }
  study() {}
  getWeight() {
    console.log(this.weight)
  }
}
  • 多态,同一接口的不同实现
class People {
  constructor(name) {
    this.name = name
  }
  saySomething() {}
}

class A extends People {
  constructor(name) {
    super(name)
  }
  saySomething() {
    console.log("A")
  }
}

class B extends People {
  constructor(name) {
    super(name)
  }
  saySomething() {
    console.log("B")
  }
}

JS应用

class jQuery {
  constructor(selector) {
    let slice = Array.prototype.slice
    let dom = slice.call(document.querySelectorAll(selector))
    let len = dom ? dom.length : 0
    for(let i = 0; i < len; i++){
      this[i] = dom[i]
    }
    this.length = len
    this.selector = selector || ''
  }
  append(node) {}
  addClass(name) {}
  html(data) {}
}
window.$ = function(selector) {
  // 工厂模式
  return new jQuery(selector)
}

转向某事的意思

  • 编程:序列、判断、循环 - 结构化
  • 面向对象 - 数据结构化
  • 对于计算机来说,结构是最简单的

UML类图

  • 泛化,表示继承
  • 关联,表示引用
JavaScript设计原则
class People {
  constructor(name, house) {
    this.name = name
    this.house = house
  }
  saySomething() {}
}

class A extends People {
  constructor(name, house) {
    super(name, house)
  }
  saySomething() {
    console.log("A")
  }
}

class B extends People {
  constructor(name, house) {
    super(name, house)
  }
  saySomething() {
    console.log("B")
  }
}

class House {
  constructor(city) {
    this.city = city
  }
  showCity() {
    console.log(this.city)
  }
}
let aHouse = new House('上海')
let a = new A('a', aHouse)
let b = new B('b')

设计原则

使用说明

  • 小即有趣
  • 允许每个程序做一件事
  • 快速原型
  • 便携式营销成功
  • 使用简单的软件存储数据利用软件)
  • 使用shell脚本来增加功能性和便携性
  • 避免过多的用户界面
  • 过滤所有程序

一个小指南

  • 允许用户配置环境
  • 尽量保持内核小而轻
  • 使用小写并保持简短
  • 沉默是金
  • 整体
  • 找到 90% 的解决方案

SOLID 五个设计原则

  • S-单一职责原则
    • 程序只做一件事
    • 如果功能太复杂,则进行划分,保持各个部分独立
  • O-开闭原则s,关闭修改
  • 随着需求的增加,开发新代码,但不要修改现有代码
  • L-里氏替换规则
    • 子类可以覆盖父类
    • 其中子类可能会出现,类可能会出现
    • 较少用于JS(少用弱类型和继承)
  • I-接口独立原则
    • 保持接口唯一、独立,避免“胖接口”的出现
    • JS 中没有好的接口(TypeScript 例外),使用less
    • 与主规则类似,单一职责
  • D 依赖导致规则
    • 面向接口编程,依赖于抽象而不是具体
    • 用户只关心接口,忽略具体类 的实现 未在 JS 中使用(无接口和弱类型)
  • 设计模式

    创意型

    • 商业模式(商业模式、抽象商业模式、制造商模式)
    • 需要独特
    • 需要原型

    结构类型

    行为

    • 战略线
    • 程序线
    • 控制线
    • 叛徒线
    • 责任线

      政府布

    • 家访者
    • 中级模式
    • 口译员模式

    面试问题

    • 乘坐出租车时,可以乘坐私家车或特快车。所有汽车都有序列号和名称
    • 不同的汽车有不同的价格。快车每公里1元,私家车每公里2元
    • 行程开始时显示车辆信息
    • 行程结束时显示票价(如果5公里只是行程)
    JavaScript设计原则
    • 一个停车场分为三层,每层有100个停车位,每辆车,每层停车位数量。显示
    • 进车时、下车时摄像头可以检测到车号并给车计时
    JavaScript设计原则
    // 车辆
    class Car {
      constructor(num) {
        this.num = num
      }
    }
    // 摄像头
    class Camera {
      shot(car) {
        return {
          num: car.num,
          inTime: Date.now()
        }
      }
    }
    // 出口显示屏
    class Screen {
      show(car, inTime) {
        console.log(car.num, Date.now() - inTime)
      }
    }
    // 停车场
    class Park {
      constructor(floors) {
        this.floors = floors || []
        this.camera = new Camera()
        this.screen = new Screen()
        this.carList = {} //存储摄像头拍摄返回的车辆信息
      }
      in(car) {
        // 通过摄像头获取信息
        const info = this.camera.shot(car)
        // 听到某个停车位
        const i = parseInt(Math.random() * 100 % 100)
        const place = this.floors[0].places[i]
        place.in()
        info.place = place
        // 记录信息
        this.carList[car.num] = info
      }
      out(car) {
        // 获取信息
        const info = this.carList[car.num]
        // 将停车位清空
        const place = info.place
        place.out()
        // 显示时间
        this.screen.show(car, info.inTime)
        // 清空记录
        delete this.carList[car.num]
      }
      emptyNum() {
        return this.floors.map(floor => {
          return floor.index + "-" + floor.emptyPlaceNum()
        })
      }
    }
    // 层
    class Floor {
      constructor(index, places) {
        this.index = index
        this.places = places || []
      }
      emptyPlaceNum() {
        let num = 0
        this.places.forEach(p => {
          if(p.empty){
            num = num + 1
          }
        })
        return num
      }
    }
    // 车位
    class Place {
      constructor() {
        this.empty = true
      }
      in() {
        this.empty = false
      }
      out() {
        this.empty = true
      }
    }
    // 测试
    // 初始化停车场
    const floors = []
    for(let i = 0; i < 3; i++) {
      const places = []
      for(let j = 0; j < 100; j++) {
        places[j] = new Place()
      }
      floors[i] = new Floor(i + 1, places)
    }
    const park = new Park(floors)
    // 初始化车辆
    const car1 = new Car(100)
    const car2 = new Car(200)
    const car3 = new Car(300)
    
    park.emptyNum()
    park.in(car1)
    park.out(car1)

    版权声明

    本文仅代表作者观点,不代表Code前端网立场。
    本文系作者Code前端网发表,如需转载,请注明页面地址。

    发表评论:

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

    热门