Jak zaprojektować parking przy użyciu zasad obiektowych?
Projektowanie parkingu przy użyciu zasad obiektowych polega na podziale systemu na klasy, atrybuty i metody, które odzwierciedlają byty ze świata rzeczywistego. Kluczowe komponenty, takie jak pojazdy i miejsca parkingowe, można modelować jako obiekty, a interakcje, takie jak parkowanie, można obsługiwać za pomocą metod. Takie podejście sprzyja ponownemu wykorzystaniu modułowości i łatwości konserwacji, dzięki czemu system jest łatwy w rozbudowie i zarządzaniu.
Jak zaprojektować parking w oparciu o zasady obiektowe? Założenia
Dla naszych celów w tej chwili przyjmiemy następujące założenia. Przyjęliśmy te konkretne założenia, aby dodać trochę złożoności do problemu bez dodawania zbyt wielu rzeczy.
- Parking jest wielopoziomowy. Każdy poziom ma wiele rzędów plam.
- Na parkingu można zaparkować motocykle, samochody osobowe i autobusy.
- Na parkingu znajdują się miejsca dla motocykli, miejsca kompaktowe i duże.
- Motocykl można zaparkować w dowolnym miejscu.
- Samochód można zaparkować albo w jednym kompaktowym miejscu, albo w jednym dużym miejscu.
- Autobus może zaparkować na pięciu dużych miejscach, następujących po sobie i w tym samym rzędzie. Nie może parkować w małych miejscach. W poniższej implementacji utworzyliśmy abstrakcyjną klasę Pojazd, z której dziedziczą Samochód Autobus i Motocykl.
Projektowanie obiektowe
Zaczynamy od stworzenia niezbędnych klas i upewnienia się, że każda klasa ma jasno określoną odpowiedzialność. Rozłóżmy projekt, koncentrując się na interakcji poszczególnych klas i metod.
1. Klasa pojazdu
The Vehicle klasa definiuje wspólne atrybuty i zachowania dla wszystkich typów pojazdów. Będzie służyć jako klasa bazowa dla bardziej specyficznych typów pojazdów, takich jak Bus Car I Motorcycle .
public abstract class Vehicle { protected String licensePlate ; protected int spotsNeeded ; protected VehicleSize size ; public Vehicle ( String licensePlate VehicleSize size ) { this . licensePlate = licensePlate ; this . size = size ; this . spotsNeeded = ( size == VehicleSize . Large ) ? 5 : 1 ; } public int getSpotsNeeded () { return spotsNeeded ; } public VehicleSize getSize () { return size ; } public String getLicensePlate () { return licensePlate ; } public abstract boolean canFitInSpot ( ParkingSpot spot ); }
2. Klasy pojazdów betonowych
Autobus : Autobus wymaga 5 kolejnych dużych miejsc.
Java public class Bus extends Vehicle { public Bus ( String licensePlate ) { super ( licensePlate VehicleSize . Large ); } public boolean canFitInSpot ( ParkingSpot spot ) { return spot . getSpotSize () == VehicleSize . Large ; } }
Samochód : Samochód można zaparkować na małych lub dużych miejscach.
Java public class Car extends Vehicle { public Car ( String licensePlate ) { super ( licensePlate VehicleSize . Compact ); } public boolean canFitInSpot ( ParkingSpot spot ) { return spot . getSpotSize () == VehicleSize . Compact || spot . getSpotSize () == VehicleSize . Large ; } }
Motocykl : Motocykl można zaparkować w dowolnym miejscu
Java public class Motorcycle extends Vehicle { public Motorcycle ( String licensePlate ) { super ( licensePlate VehicleSize . Motorcycle ); } public boolean canFitInSpot ( ParkingSpot spot ) { return true ; // Can park in any spot } }
3. Klasa ParkingSpot
The ParkingSpot klasa reprezentuje indywidualne miejsce parkingowe na parkingu. Odpowiada za zarządzanie jego dostępnością i weryfikację, czy konkretny pojazd zmieści się w danym miejscu.
- Mogliśmy to zaimplementować, tworząc klasy dla LargeSpot CompactSpot i MotorcycleSpot, które dziedziczą z ParkingSpot, ale to prawdopodobnie przesada.
- Plamy prawdopodobnie nie zachowują się inaczej niż ich rozmiar.
public class ParkingSpot { private Vehicle vehicle ; private VehicleSize spotSize ; private int row ; private int spotNumber ; private Level level ; public ParkingSpot ( Level level int row int spotNumber VehicleSize spotSize ) { this . level = level ; this . row = row ; this . spotNumber = spotNumber ; this . spotSize = spotSize ; this . vehicle = null ; } public boolean isAvailable () { return vehicle == null ; } public boolean canFitVehicle ( Vehicle vehicle ) { return isAvailable () && vehicle . canFitInSpot ( this ); } public void parkVehicle ( Vehicle vehicle ) { if ( canFitVehicle ( vehicle )) { this . vehicle = vehicle ; } } public void removeVehicle () { this . vehicle = null ; } public VehicleSize getSpotSize () { return spotSize ; } public int getRow () { return row ; } public int getSpotNumber () { return spotNumber ; } }
4. Klasa poziomu parkingu
The Level klasa reprezentuje poziom na parkingu. Zarządza zbiorem miejsc parkingowych i zapewnia metody parkowania i usuwania pojazdów.
public class Level { private int levelNumber ; private ParkingSpot [] spots ; public Level ( int levelNumber int numSpots ) { this . levelNumber = levelNumber ; this . spots = new ParkingSpot [ numSpots ] ; } public boolean parkVehicle ( Vehicle vehicle ) { for ( ParkingSpot spot : spots ) { if ( spot . canFitVehicle ( vehicle )) { spot . parkVehicle ( vehicle ); return true ; } } return false ; } public boolean removeVehicle ( Vehicle vehicle ) { for ( ParkingSpot spot : spots ) { if ( spot . isOccupied () && spot . getVehicle (). equals ( vehicle )) { spot . removeVehicle (); return true ; } } return false ; } }
5. Klasa ParkingLot
The ParkingLot klasa reprezentuje cały parking. Zarządza wieloma poziomami i zapewnia metody parkowania i usuwania pojazdów z parkingu.
public class ParkingLot { private Level [] levels ; public ParkingLot ( int numLevels int numSpotsPerLevel ) { levels = new Level [ numLevels ] ; for ( int i = 0 ; i < numLevels ; i ++ ) { levels [ i ] = new Level ( i numSpotsPerLevel ); } } public boolean parkVehicle ( Vehicle vehicle ) { for ( Level level : levels ) { if ( level . parkVehicle ( vehicle )) { return true ; } } return false ; // Parking failed (no spots available) } public boolean removeVehicle ( Vehicle vehicle ) { for ( Level level : levels ) { if ( level . removeVehicle ( vehicle )) { return true ; } } return false ; // Removal failed (vehicle not found) } }
6. Klasy Ticket i PaymentService
Aby zarządzać sprzedażą biletów i płatnościami, dodajemy Ticket I PaymentService zajęcia.
Klasa biletowa : Reprezentuje bilet wydawany podczas parkowania pojazdu. Rejestruje czas wjazdu i wyjazdu pojazdu z parkingu.
Java public class Ticket { private Vehicle vehicle ; private Date issueTime ; private Date exitTime ; public Ticket ( Vehicle vehicle ) { this . vehicle = vehicle ; this . issueTime = new Date (); } public void setExitTime ( Date exitTime ) { this . exitTime = exitTime ; } public long getDuration () { return ( exitTime . getTime () - issueTime . getTime ()) / 1000 ; // Time in seconds } }
Klasa usługi płatności : Odpowiedzialny za obliczanie opłat parkingowych i przetwarzanie płatności.
Jawa publiczny klasa Usługa płatności { publiczny podwójnie oblicz opłatę ( Bilet bilet ) { długi czas trwania = bilet . getDuration (); // Prosty model opłat: `text`=