この記事では、Go での駐車場システムの低レベル設計 (LLD) 実装について説明します。システムのさまざまな側面を調査し、各コンポーネントが他のコンポーネントとどのように相互作用するかを見ていきます。この実装は明確さと現実世界での有用性に重点を置いているため、より多くの車両タイプ、複数の支払いオプション、スポット予約などの機能を追加したい場合に簡単に拡張できます。
このシステムは、駐車フロアと駐車スペースの管理、車両の駐車と駐車解除、支払いの処理などのタスクを処理します。また、同時アクセスに対してスレッドセーフであることも保証します。そのため、より大きなシステムに拡張する必要がある場合でも、圧力がかかっても機能しなくなることはありません。
私たちの設計には 6 つの主要コンポーネントが含まれています:
私たちの駐車場はシングルトンパターンを使用しています。つまり、駐車場のインスタンスは 1 つだけあり、一度作成されるとアプリケーション全体で再利用されます。これを機能させるコードは次のとおりです:
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 からアクセスされた場合でも、インスタンスが 1 つだけ作成されることが保証されます。
駐車場には複数のフロアがあり、各フロアにさまざまな種類の車両 (乗用車、バン、トラック、オートバイなど) 用に指定された駐車スペースがあります。駐車場にフロアを追加するには、AddFloor メソッドを使用します。
func (p *ParkingLot) AddFloor(floorID int) { p.floors = append(p.floors, NewParkingFloor(floorID)) }
各フロアは、車両タイプごとにスポットを整理する NewParkingFloor 関数を使用して作成されます。
各パーキングスポットは、特定の車両タイプ (車やバイクなど) に関連付けられています。これにより、システムは各スポットに駐車できる車両を管理および制限できます。以下に、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 }
ミューテックス ロックを使用して、一度に 1 台の車両のみがその場所に駐車できるようにします。
すべての車両には、入場時間、退場時間、駐車場所、合計料金が記載されたチケットが発行されます。このチケットは車両の出庫時に更新され、料金は駐車時間に基づいて計算されます。
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 を実装しています。
各部分がフローの中でどのように組み合わされるかを見てみましょう:
この駐車場システムは、より複雑なシステムを構築するための簡素化された出発点です。フロアとスポットの管理、車両の駐車と降車、基本的な支払いプロセスの基本について説明しました。
完全なコード実装については、次のリポジトリを確認してください:
Go での低レベル システム設計 リポジトリへようこそ!このリポジトリには、Go で実装されたさまざまな低レベルのシステム設計の問題とその解決策が含まれています。主な目的は、実際の例を通じてシステムの設計とアーキテクチャを実証することです。
低レベルのシステム設計には、システム アーキテクチャの中核概念を理解し、拡張性、保守性、効率性の高いシステムを設計することが含まれます。このリポジトリは、Go を使用したさまざまな問題やシナリオの解決策をカバーしようとします。
このリポジトリの最初のプロジェクトは、駐車場システムです。このシステムは、車両を駐車および駐車解除できる駐車場をシミュレートします。以下を示します:
以上がシステム設計: Go で駐車場システムを構築するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。