Как да проектираме паркинг, използвайки обектно-ориентирани принципи?
Проектирането на паркинг с помощта на обектно-ориентирани принципи включва разбиване на системата на атрибути на класове и методи, които отразяват обекти от реалния свят. Ключови компоненти като превозни средства и места за паркиране могат да бъдат моделирани като обекти, докато взаимодействията като паркиране могат да бъдат управлявани чрез методи. Този подход насърчава възможността за повторна употреба и поддръжка на модулността, което прави системата лесна за разширяване и управление.
Как да проектираме паркинг, използвайки обектно-ориентирани принципи? Предположения
За нашите цели в момента ще направим следните допускания. Направихме тези конкретни предположения, за да добавим малко сложност към проблема, без да добавяме твърде много.
- Паркингът е на няколко нива. Всяко ниво има няколко реда петна.
- На паркинга могат да се паркират мотоциклети, автомобили и автобуси.
- Паркингът разполага с места за мотоциклети компактни места и големи места.
- Мотоциклетът може да паркира на всяко място.
- Една кола може да паркира или на едно компактно място, или на едно голямо място.
- Автобус може да паркира на пет големи места, които са последователни и в рамките на един ред. Не може да паркира на малки места. В изпълнението по-долу създадохме абстрактен клас Vehicle, от който се наследяват Car Bus и Motorcycle.
Обектно-ориентиран дизайн
Започваме със създаването на необходимите класове и гарантираме, че всеки клас има ясна единична отговорност. Нека разбием дизайна с акцент върху това как всеки клас и метод си взаимодействат.
1. Клас на превозното средство
The Vehicle класът определя общи атрибути и поведение за всички видове превозни средства. Той ще служи като базов клас за по-специфични типове превозни средства като Bus Car и 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. Класове бетонови превозни средства
автобус : Автобус изисква 5 последователни големи петна.
Java public class Bus extends Vehicle { public Bus ( String licensePlate ) { super ( licensePlate VehicleSize . Large ); } public boolean canFitInSpot ( ParkingSpot spot ) { return spot . getSpotSize () == VehicleSize . Large ; } }
кола : Колата може да паркира както на компактни, така и на големи места.
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 ; } }
мотоциклет : Мотоциклетът може да паркира на всяко място
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. Клас ПаркингСпот
The ParkingSpot клас представлява индивидуално паркомясто в паркинга. Той отговаря за управлението на неговата наличност и проверката дали конкретно превозно средство може да се побере на място.
- Можехме да приложим това, като имаме класове за LargeSpot CompactSpot и MotorcycleSpot, които наследяват от ParkingSpot, но това вероятно е преуморено.
- Петната вероятно нямат различно поведение освен размерите си.
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. Клас на ниво на паркиране
The Level клас представлява ниво на паркинга. Той управлява набор от места за паркиране и предоставя методи за паркиране и премахване на превозни средства.
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. Клас паркинг
The ParkingLot клас представлява целият паркинг. Той управлява множество нива и предоставя методи за паркиране и премахване на превозни средства от паркинга.
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. Класове за билети и PaymentService
За да управляваме билетите и плащанията, добавяме Ticket и PaymentService класове.
Клас на билета : Представлява билета, издаден при паркиране на превозно средство. Той записва времето, когато автомобилът влиза и излиза от паркинга.
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 } }
Клас PaymentService : Отговаря за изчисляването на таксата за паркиране и обработката на плащанията.
Java публичен клас PaymentService { публичен двойно изчислиТакса ( Билет билет ) { дълго продължителност = билет . getDuration (); // Прост модел на такса: `текст`=