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