以下是某场的一道面试题(也许):
1、一个泊车场,车辆入场时,摄像头纪录下车辆信息
2、屏幕上显现所吸收的车辆的信息状况(车牌号)以及各层车位的车位余量
3、泊车场一共四层车位,个中的三层都为一般车位,另有一层为迥殊车位(体如今泊车计费价格上面的差别)
看到第一个条件的时刻,我也许知道了这道题考核的应当是面向对象相干的,三个条件看完后以及基本确认了。
说到这里,简朴地说一下面向对象,至于什么是面向对象我这里就不多说了,每一个人也都有本身差别的明白,包含它的三要素(封装、继承、多态)。
简朴地说一下为何我们要面向对象,为何要运用面向对象?说一下我的明白
先抛开面向对象,起首计算机的 递次实行 不过就是 递次、推断、轮回 我们如今一切用到的言语包含c、java、php… 没有别的的, 如js中的 if…else, switch…case…就是推断,for,while就是轮回,也包含一些遍历、递归也都是基于这三种体式格局!我们天天所产出的代码,一切的这些都是经由过程递次、推断和轮回这三个体式格局都能轻松搞定,没有第四种体式格局,为何呢?由于我们经由过程这三种体式格局来处置惩罚就完成了一个构造化的题目,也就是我们经由过程这三个就能够满足一切的需求,也就不需要第四个了如许的化对我们的递次就已构造化了,关于编译器也能很高效的实行、剖析这些东西, 外插一嘴,goto语句实在就是游离在这三个以外,会致使递次、逻辑的杂沓,很少有效基本被镌汰了,不能说他由于效力低,它的效力能够会很高,然则由于离开了构造化,所以至少在营业代码上我们少少运用它。
说到这里,也就是程勋实行我们都简化成 这个构造,而面向对象也让我们的数据也简化了即构造化(这句话也不是我说的,而是ruby言语的作者),书里说了,面向对象是为了模仿、示意事宜得万物,比方人、鸟类、到详细服务员类,有详细行动的类。实在js内里向对象意义基本不拘泥于此,书上的只是为了让我们好入门好进修罢了,它的意义是将零星的数据举行构造化。计算机有个缺点,构造化的递次关于它来讲是最简朴的!
简朴解释一下,我们浏览器加载网页加载的是什么?是流,流是什么呢?实在就是字符串,虽然我们看到今后是html,css,js代码,然则代码不就是字符串嘛,那我们字符串怎样办,浏览器拿到字符串起首就是dom节点的剖析然后天生天生衬着树(衬着树与dom树差别的处所在于,dom树会把一切的dom节点都展现出来,衬着树只会展现display非none的元素),都是一步步递次实行的。
比拟来讲,递次也是云云了,假如我们的递次中充满了狼藉的数据,那我们还怎样根据构造化的请求去操纵呢?比方说,经由过程人做一个对象,人有表面,行动,状况(吃、传、喝、高矮胖瘦)这么多东西能够集成在一个对象中来操纵,然则假如没有面向对象,这些特性,行动也就狼藉了,一旦狼藉了今后还怎样治理,而且这只是一个人,就有这么多东西,再来十个,一百个,再来只狗类呢?我们的递次就成了一盘散沙了,固然这些只是举例子,详细营业还要拿来详细剖析。所以面向对象不仅相符计算机所喜欢的构造化,还能让我们治理起来,保护起来,都相符构造化。
再援用双越先生的一句话:编程就应当简朴&笼统。
有一篇小说内里有一段话我以为还蛮有意思的,初期的人们之所以没有设想出来计算机,就是由于他们想的不够简朴,而不是不够庞杂,实在计算机很简朴,不就是0和1吗。
一切说我们编程,设想时刻要做到 构造化,简朴+笼统,笼统完今后才简朴,简朴的条件是我们应当笼统好,我以为这就是我们为何要面向对象最主要的缘由,我们之所以面向对象编程就是由于它能够笼统,能够扩大。而不是面向详细,能够这些话关于初学前端的来讲不好明白,然则跟着你工作时间的提拔,置信很快就会明白的。
**回到面试题,我们来剖析**
这个面试题,假如我们没有面向对象,面向笼统的观点, 那我们应当很快就能够拿起键盘了,一个泊车场,三个一般车位,一个奢华车位,一个摄像头,一个大屏幕显现器,林林总总的车,能够我们很快就能够做完,‘设想完’,毕竟面向详细是真的很简朴,请求什么我就做什么。。。
不过说返来,假如面试官再让你减一个车位或许增添两个奢华车位,加两个摄像头?假如根据我们之前的来写,简朴。。。改一下不就行了,加一个奢华车位,加两个摄像头。。。实在到这里想必已凉凉了。
下面我们来运用面向对象
类图这里就不再画了
起首面试题中所提到的我们都能够算作类,比方泊车场是一个类吧,它内里的车位是一个类吧,摄像头,屏幕。。。我们都能够看作是类
泊车场,有层位,有摄像头,屏幕,所以我们先来建立一个泊车场,这一类
class Park {
constructor () {
}
}
泊车场有层位,层位内里有多少车位
class Floor {
constructor (num, places) {
this.num = num
this.places = places
}
}
车位也归为一类,车位有本身的状况,有车,无车
class Place {
constructor () {
this.empty = true
}
}
车位分为一般车位,奢华车位,然则不论是一般照样奢华,他们也都有本身的状况,有车,无车,所以我们直接让这两个类继承车位类
一般车位
class NormalPlace extends Place{
constructor () {
super()
}
}
奢华车位
class SpecialPlace extends Place{
constructor () {
super()
}
}
摄像头
class Camera {
constructor () {
}
}
电脑,能够纪录一切车的数据
class Computer {
constructor () {
this.symbols = {}
}
}
// 屏幕
class Screen {
}
如许一看我们一切类都建立完了,差的是来剖析他们的行动,状况,联络,这里不再多做剖析。只举一个简朴的例子,然后上完全代码
泊车场, 有层 摄像图 屏幕,有相差车时所发作的行动
class Park {
constructor (floors) {
this.floors = floors
this.camera = new Camera()
this.screen = new Screen()
}
in (car) {
}
out (car) {
}
}
我本身写了一个简朴的demo,固然也没有斟酌得迥殊仔细
***完全代码***
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body,html{
height: 100%;
}
ul,li {
list-style: none;
}
#inform {
text-align: center;
color: #9f9f9f;
font-size: 18px;
}
#inform span {
color: #ff4a3d;
}
#earch {
text-align: center;
font-size: 20px;
color: #2963ff;
}
</style>
</head>
<body>
<ul id="inform">
<li>第一层车位数目100,空余车位数目 <span data-num=1>100</span></li>
<li>第二层车位数目100,空余车位数目 <span data-num=2>100</span></li>
<li>第三层车位数目100,空余车位数目 <span data-num=3>100</span></li>
<li>第四层车位数目 20,空余车位数目 <span data-num=4> 20</span></li>
</ul>
<p style="text-align: center; color: #5eb4ff">收入 <span id="price">0</span> 元</p>
<ul id="earch">
<li>统计</li>
</ul>
<script>
let priced = document.getElementById('price')
let earch = document.getElementById('earch')
class Camera {
constructor () {
this.computer = new Computer()
}
record (car, place, floor) {
this.computer.show(car)
return {
num: car.num,
symbol: car.symbol,
inTime: new Date(),
place,
floor
}
}
}
class Computer {
constructor () {
this.symbols = {}
}
show (car) {
console.log(`车牌号为${car.num}的${car.symbol}驶入`)
if (this.symbols[car.symbol] !== undefined) {
this.symbols[car.symbol] = this.symbols[car.symbol] + 1
document.getElementById(car.symbol).innerText = this.symbols[car.symbol]
} else {
this.symbols[car.symbol] = 0
earch.innerHTML = earch.innerHTML + `<li>${car.symbol} <span id="${car.symbol}">${0}</span> 辆<li>`
}
}
}
class Screen {
reload (f, t) {
let dom = Array.prototype.slice.apply(document.querySelectorAll('#inform span'))
if (t === '1') {
dom.map(el => {
if (el.dataset.num === f + 1 + '') {
el.innerText = --el.innerText
}
})
} else {
dom.map(el => {
if (el.dataset.num === f + 1 + '') {
el.innerText = ++el.innerText
}
})
}
}
}
class Park {
constructor (floors) {
this.floors = floors
this.camera = new Camera()
this.screen = new Screen()
this.carList = {}
this.fullFloor = []
this.wait = []
}
in (car) {
let canChoice = []
let floors = this.floors
floors.map((el, index) => {
if (el.emptys > 0) {
canChoice.push(index)
}
})
if (canChoice.length === 0) {
if (Math.random() > 0.2) {
console.warn('没有找到车位,撤了')
return 'back'
} else {
console.warn(`没有找到车位,继承守候`)
this.in(car)
return 'wait'
}
}
let fi = canChoice[Math.floor(Math.random() * canChoice.length)]
let canChoicePlaceIndex = []
let places = floors[fi].places
places.map((el, index) => {
if (el.empty) {
canChoicePlaceIndex.push(index)
}
})
let pi = Math.floor(Math.random() * canChoicePlaceIndex.length)
this.carList[car.num] = this.camera.record(car, pi, fi)
places[pi].in(floors[fi])
this.screen.reload(fi, '1')
let outs = Math.ceil(Math.random() * 100000 + 5000)
setTimeout(() => {
this.out(car)
}, outs)
}
out (car) {
let place = this.floors[this.carList[car.num].floor].places[this.carList[car.num].place]
place.out(this.floors[this.carList[car.num].floor])
let price = (new Date() - this.carList[car.num].inTime)/1000 * place.price
this.screen.reload(this.carList[car.num].floor)
console.log(`车牌号为${car.num}驶出, 收费 ${price} 元`)
priced.innerText = (Number(priced.innerText) + Number(price)).toFixed(2)
delete this.carList[car.num]
}
}
class Floor {
constructor (num, places) {
this.num = num
this.places = places
this.emptys = places.length
}
inP () {
this.emptys--
}
outP () {
this.emptys++
}
}
class Place {
constructor () {
this.empty = true
}
in (floor) {
this.empty = false
floor.inP()
}
out (floor) {
this.empty = true
floor.outP()
}
}
class NormalPlace extends Place{
constructor () {
super()
this.color = 'blue'
this.price = 10
}
}
class SpecialPlace extends Place{
constructor () {
super()
this.color = 'yellow'
this.price = 60
}
}
class Car {
constructor (type, num, symbol) {
this.permit = type === '1'
this.num = num
this.symbol = symbol
}
}
// 以下部份悉数为合营完成,请勿浪费时间寓目
let Floors = []
for (let i = 0; i < 3; i++) {
let places = []
for (let j = 0; j < 100; j++) {
places.push(new NormalPlace())
}
Floors.push(new Floor(i + 1, places))
}
let specialPlace = []
for (let i = 0; i < 20; i++) {
specialPlace.push(new SpecialPlace())
}
Floors.push(new Floor(4, specialPlace))
let park = new Park(Floors)
var str = []
for(var i = 65; i < 91; i++){
str.push(String.fromCharCode(i))
}
let test = {
s: ['京', '冀', '黑', '蒙', '陕', '户', '津', '赣', '浣', '深', '藏', '疆' ],
n: str,
u: ['奔驰', '劳斯莱斯', '路虎', '群众', '保时泰', '保时捷', '兰博基尼', 'QQ', '丰田', '本田', '吉祥', '宝马', '迈巴赫', '公交车', '火车', '坦克', '红旗', '捷豹', '法拉利', '宾利']
}
let enterTime = 100
setInterval( () => {
let number = test.s[Math.ceil(Math.random() * test.s.length) - 1] +
test.n[Math.ceil(Math.random() * test.n.length) - 1] +
Math.floor(Math.random() * 100000)
let na = test.u[Math.ceil(Math.random() * test.u.length) - 1]
let car = new Car('1', number, na)
park.in(car)
enterTime = Math.floor(Math.random() * 50)
}, enterTime)
</script>
</body>
</html>
代码能够直接粘贴到html里,直接运转翻开,人人只要看各个类之间的联络就能够够,详细到行动的逻辑代码只是怎样简朴想怎样写就怎样写的,固然也有没斟酌周全的,比方各个车位的价格应当也是动态的,为了赶时间,很多东西我都直接定死了。
笼统好了今后,如许不论是增添削减变动价格我们都能够天真地处置惩罚,每一个类最基本的行动和要领几乎是不变得,我们只需要变轻易变得笼统起来,封装起来。今后, 就变得‘简朴’
迎接一同讨论,人人共同进步!