首頁  >  文章  >  後端開發  >  系統設計:用Go建造停車場系統

系統設計:用Go建造停車場系統

DDD
DDD原創
2024-11-11 22:03:02848瀏覽

在本文中,我們將介紹 Go 中停車場系統的低階設計 (LLD) 實作。我們將探索系統的不同方面,並了解每個組件如何與其餘組件互動。此實現側重於清晰度和現實世界的實用性,因此如果您想添加更多車輛類型、多種付款選項或現貨預訂等功能,您可以輕鬆擴展它。

系統處理諸如管理停車樓層和停車位、停放車輛和處理付款等任務。我們還將確保它對於並發存取是線程安全的,因此如果我們需要將其擴展到更大的系統,它不會在壓力下崩潰。


核心組件

我們的設計包括六個主要組成部分:

  1. 停車場 - 管理樓層和停車作業的主要入口點。
  2. 停車場 - 每層都有多個停車位,可停放不同類型的車輛。
  3. 停車位 - 代表可停放特定類型車輛的停車位。
  4. 停車票 - 追蹤進入/退出時間、停車費用和相關車輛。
  5. 付款系統 - 處理停車費計算與付款處理。
  6. 車輛類型 - 支援不同類型的車輛(汽車、貨車、卡車和摩托車)。每種類型的每小時費用不同。

辛格頓停車場

我們的停車場使用單例模式。這意味著停車場只有一個實例,該實例創建一次並在整個應用程式中重複使用。這是使其正常工作的程式碼:

var (
    parkingLotInstance *ParkingLot
    once               sync.Once
)

type ParkingLot struct {
    Name   string
    floors []*ParkingFloor
}

func GetParkingLotInstance() *ParkingLot {
    once.Do(func() {
        parkingLotInstance = &ParkingLot{}
    })
    return parkingLotInstance
}

使用sync.Once,我們確保只建立一個實例,即使被多個 goroutine 存取也是如此。

停車場樓層管理

停車場有多層,每層都有不同車輛類型(例如汽車、貨車、卡車和摩托車)的指定停車位。若要為停車場新增樓層,我們使用 AddFloor 方法:

func (p *ParkingLot) AddFloor(floorID int) {
    p.floors = append(p.floors, NewParkingFloor(floorID))
}

每個樓層都是使用 NewParkingFloor 函數創建的,該函數按車輛類型組織停車位。

停車位

每個 ParkingSpot 都與特定的車輛類型(例如汽車或摩托車)相關聯。這使得系統能夠管理和限制每個停車位可以停放的車輛。這是 ParkingSpot 結構和 ParkVehicle 方法:

type ParkingSpot struct {
    SpotID         int
    VehicleType    vehicles.VehicleType
    CurrentVehicle *vehicles.VehicleInterface
    lock           sync.Mutex
}

func (p *ParkingSpot) ParkVehicle(vehicle vehicles.VehicleInterface) error {
    p.lock.Lock()
    defer p.lock.Unlock()

    if vehicle.GetVehicleType() != p.VehicleType {
        return fmt.Errorf("vehicle type mismatch: expected %s, got %s", p.VehicleType, vehicle.GetVehicleType())
    }
    if p.CurrentVehicle != nil {
        return fmt.Errorf("parking spot already occupied")
    }

    p.CurrentVehicle = &vehicle
    return nil
}

我們使用互斥鎖來確保同一時間只能停放一輛車。

停車券

每輛車都會收到一張票,上面有進入時間、退出時間、停車位和總費用。此票會在車輛退出時更新,並根據停車時間計算費用。

var (
    parkingLotInstance *ParkingLot
    once               sync.Once
)

type ParkingLot struct {
    Name   string
    floors []*ParkingFloor
}

func GetParkingLotInstance() *ParkingLot {
    once.Do(func() {
        parkingLotInstance = &ParkingLot{}
    })
    return parkingLotInstance
}

CalculateTotalCharge 方法根據車輛類型和持續時間計算停車費。

支付系統

PaymentSystem 類別處理付款,依照是否支付所需金額更新付款狀態:

func (p *ParkingLot) AddFloor(floorID int) {
    p.floors = append(p.floors, NewParkingFloor(floorID))
}

ProcessPayment 函數檢查金額並將付款狀態更新為「已完成」或「失敗」。

新增車輛類型

我們的系統支援不同類型的車輛(汽車、貨車、卡車和摩托車)。每種類型的每小時費用不同。這是透過在單獨的車輛包中設定 VehicleType 和 VehicleInterface 來實現的:

type ParkingSpot struct {
    SpotID         int
    VehicleType    vehicles.VehicleType
    CurrentVehicle *vehicles.VehicleInterface
    lock           sync.Mutex
}

func (p *ParkingSpot) ParkVehicle(vehicle vehicles.VehicleInterface) error {
    p.lock.Lock()
    defer p.lock.Unlock()

    if vehicle.GetVehicleType() != p.VehicleType {
        return fmt.Errorf("vehicle type mismatch: expected %s, got %s", p.VehicleType, vehicle.GetVehicleType())
    }
    if p.CurrentVehicle != nil {
        return fmt.Errorf("parking spot already occupied")
    }

    p.CurrentVehicle = &vehicle
    return nil
}

我們可以透過呼叫NewCar、NewVan、NewTruck等來創建新的車輛,它們都實現了VehicleInterface。


將一切整合在一起

讓我們看看各個部分如何在流程中組合在一起:

  • 建立停車場:呼叫 GetParkingLotInstance() 並使用 AddFloor 新增樓層。
  • 尋找停車位並停放車輛:ParkVehicle 方法尋找可用停車位,根據車輛類型對其進行驗證,並產生票證。
  • Unpark Vehicle 並處理付款:UnparkVehicle 產生總費用,啟動支付系統,並完成交易。

這個停車場系統是建造更複雜系統的簡化起點。我們介紹了樓層和停車位管理、車輛停車和出庫以及基本付款流程的基礎知識。

有關完整程式碼實現,請檢查以下儲存庫:

System Design: Building a Parking Lot System in Go 主題樹 / 低級設計 golang

Golang 中的底層系統設計解決方案

Go 中的底層系統設計

歡迎來到Go 中的低階系統設計 儲存庫!此儲存庫包含各種低階系統設計問題及其在 Go 中實現的解決方案。主要目的是透過實際範例展示系統的設計和架構。

目錄

  • 概述
  • 停車場系統
  • 電梯系統
  • 圖書館管理系統
  • 自動販賣機系統
  • 社群媒體平台

概述

底層系統設計涉及理解系統架構的核心概念以及設計可擴展、可維護和高效的系統。該儲存庫將嘗試涵蓋使用 Go 的各種問題和場景的解決方案。

停車場系統

此儲存庫中的第一個項目是停車場系統。該系統模擬一個可以停放車輛和出庫車輛的停車場。它示範了:

  • 用於管理停車場實例的單例設計模式。
  • 處理不同類型的車輛(例如汽車、卡車)。
  • 多個樓層的停車位管理。
  • 付款處理...


在 GitHub 上查看


以上是系統設計:用Go建造停車場系統的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn