設計模式: 重新認識面向對象

從一道面試題講起.
  • 某停車場,分3層,每層100車位
  • 每個車位都能夠監控到車輛的駛入和離開
  • 車輛進入前,顯示每層的空餘車位數量
  • 車輛進入時,攝像頭可識別車牌號和時間
  • 車輛出來時, 出口顯示器顯示車牌號和停車時長
分析

第一點: 顯然需要有Park,Floor,Place三個類
第二點: 每個車位(place)應有一個in和out方法監控車輛, 同時應該有一個狀態.
第三點: 顯示空餘車輛的數量, 這個行爲應該由停車場park來實現,並且是通過每個Floor的彙總
第四點: 攝像頭Class輸入的是一個車輛,記錄則由Park進行記錄,記錄後要有地方進行存儲,因此park中要有個carList屬性進行記錄.
第五點: 顯然我們還需要添加一個顯示器Screen類.需要顯示車牌號和停車時長.因此需要獲取車輛的車牌信息以及進入時間,再通過當前時間減去進入時間獲得獲得停車時長.

主要的車輛的in和out是由park進行彙總的,park的in方法裏面可能有很多步驟(攝像頭拍攝,顯示器輸出等)

可畫出UML類圖如下
在這裏插入圖片描述
最終可寫出代碼如下;

//停車場
class Park {
    constructor(floorNum, perFloor) {
        this.floors = new Array(floorNum);
        for(let i = 0; i < this.floors.length; i++) {
            this.floors[i] = new Floor(perFloor);
        }
        this.camera = new Camera()
        this.screen = new Screen()
        this.carList = {}
    }
    in(car) {
        //攝像頭記錄
        let carMsg = this.camera.shot(car)
        //停到某個車位
        const i = parseInt(Math.random() * 100 / 100)
        const place = this.floors[0].places[i]
        place.in(i)
        carMsg.place = place
        //記錄信息
        this.carList[car.num] = carMsg
    }
    out(car) {
        this.screen.showTime(this.carList[car.num])
        const place = this.carList[car.num].place
        place.out()
        delete this.carList[car.num]
    }
    emptyNum() {
        let num = 0;
        for(let i = 0; i < this.floors.length; i++) {
            let floor = this.floors[i];
            num += floor.emptyNum()
        }
        return num
    }
}
//層類
class Floor {
    constructor(num) {
        this.places = new Array(num);
        for(let i = 0; i < this.places.length; i++) {
            this.places[i]= new Place();
        }
    }
    emptyNum() {
        let num = 0;
        for(let i = 0; i < this.places.length; i++) {
            let place = this.places[i]
            if(place.empty) {
                num++
            }
        }
        return num
    }

}
//車位類
class Place {
    constructor() {
        this.empty = true
    }
    in() {
        this.empty = false
    }
    out() {
        this.empty = true
    }
}

//攝像頭類
class Camera {
    constructor() {
        
    }
    shot(car) {
        return {
            num: car.num,
            inTime: Date.now()
        }
    }
}

//顯示器類
class Screen {
    constructor() {

    }
    showTime(car) {
        let time = Date.now() - car.inTime
        console.log(`車輛${car.num}停車時長爲${time}`)
    }

}

//車輛
class Car {
    constructor(num) {
        this.num = num;
    }
}

const park = new Park(3,100)

// 初始化車輛
const car1 = new Car('A1')
const car2 = new Car('A2')
const car3 = new Car('A3')

console.log('第一輛車進入')
console.log(park.emptyNum())
park.in(car1)
console.log('第二輛車進入')
console.log(park.emptyNum())
park.in(car2)
setTimeout(()=> {
    console.log('第一輛車離開')
    park.out(car1)
    console.log('第二輛車離開')
    park.out(car2)
    console.log('第三輛車進入')
    console.log(park.emptyNum())
    park.in(car3)
    console.log('第三輛車離開')
    park.out(car3)
},1000);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章