¿Cómo diseñar un estacionamiento utilizando principios orientados a objetos?
Diseñar un estacionamiento utilizando principios orientados a objetos implica dividir el sistema en clases, atributos y métodos que reflejan entidades del mundo real. Los componentes clave, como vehículos y espacios de estacionamiento, se pueden modelar como objetos, mientras que las interacciones como el estacionamiento se pueden manejar mediante métodos. Este enfoque promueve la modularidad, la reutilización y la mantenibilidad, lo que hace que el sistema sea fácil de ampliar y administrar.
¿Cómo diseñar un estacionamiento utilizando principios orientados a objetos? Suposiciones
Para nuestros propósitos ahora haremos las siguientes suposiciones. Hicimos estas suposiciones específicas para agregar un poco de complejidad al problema sin agregar demasiado.
- El estacionamiento tiene múltiples niveles. Cada nivel tiene varias filas de puntos.
- En el aparcamiento se pueden aparcar motos, coches y autobuses.
- El aparcamiento dispone de plazas para motos, plazas compactas y plazas grandes.
- Una moto puede aparcar en cualquier lugar.
- Un automóvil puede estacionarse en un solo lugar compacto o en un solo lugar grande.
- Un autobús puede aparcar en cinco plazas grandes consecutivas y dentro de la misma fila. No puede aparcar en espacios pequeños. En la siguiente implementación, hemos creado una clase abstracta Vehículo de la que heredan Autobus y Motocicleta.
Diseño orientado a objetos
Comenzamos creando las clases necesarias y asegurándonos de que cada clase tenga una responsabilidad única y clara. Analicemos el diseño centrándonos en cómo interactúa cada clase y método.
1. Clase de vehículo
El Vehicle La clase define atributos y comportamientos comunes para todo tipo de vehículos. Servirá como clase base para tipos de vehículos más específicos como Bus Car y 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. Clases de vehículos de hormigón
Autobús : Un autobús requiere 5 plazas grandes consecutivas.
Java public class Bus extends Vehicle { public Bus ( String licensePlate ) { super ( licensePlate VehicleSize . Large ); } public boolean canFitInSpot ( ParkingSpot spot ) { return spot . getSpotSize () == VehicleSize . Large ; } }
Auto : Un coche puede aparcar tanto en plazas compactas como en plazas grandes.
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 ; } }
Motocicleta : Una moto puede aparcar en cualquier lugar.
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. Clase de estacionamiento
El ParkingSpot La clase representa un lugar de estacionamiento individual en el estacionamiento. Se encarga de gestionar su disponibilidad y verificar si un vehículo concreto cabe en el lugar.
- Podríamos haber implementado esto al tener clases para LargeSpot CompactSpot y MotorcycleSpot que heredan de ParkingSpot, pero probablemente esto sea excesivo.
- Las manchas probablemente no tengan comportamientos diferentes más allá de su tamaño.
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. Clase de nivel de estacionamiento
El Level La clase representa un nivel en el estacionamiento. Gestiona una colección de plazas de aparcamiento y proporciona métodos para aparcar y retirar vehículos.
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. Clase de estacionamiento
El ParkingLot La clase representa todo el estacionamiento. Gestiona múltiples niveles y proporciona métodos para estacionar y retirar vehículos del estacionamiento.
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. Clases de billetes y servicios de pago
Para gestionar la emisión de billetes y los pagos añadimos el Ticket y PaymentService clases.
Clase de boleto : Representa el ticket emitido cuando un vehículo estaciona. Registra la hora de entrada y salida del vehículo del aparcamiento.
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 } }
Clase de servicio de pago : Responsable de calcular la tarifa de estacionamiento y procesar los pagos.
Java público clase Servicio de pago { público doble calcular tarifa ( Boleto boleto ) { largo duración = boleto . obtenerDuración (); // Modelo de tarifa simple: `text`=