Skip to content

Commit

Permalink
Add lab03 task (#162)
Browse files Browse the repository at this point in the history
* Add lab03

* Update README.md
  • Loading branch information
desislavaa authored Oct 25, 2024
1 parent aeae84a commit a5a392a
Showing 1 changed file with 233 additions and 0 deletions.
233 changes: 233 additions & 0 deletions 03-oop-in-java-ii/lab/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
# Обектно-ориентирано програмиране с Java (част II)

## Bolt: Vehicle Renting on the Tip of Your Fingers :zap: :car: :bike: :minibus:

Една набираща популярност услуга е наемът на колела и автомобили за кратко - било то за няколко минути, часа, или пък за цял ден.
Естествено, все още съществува възможността и за по-дългосрочен наем на превозно средство за няколко дни или седмици.

Задачата ни този път е да комбинираме двете, упражнявайки знанията си за Records, Sealed Classes и Exceptions. Не всяка от тези концепции е зададена явно, така че мислете внимателно къде какво бихте могли да приложите.

:warning: **Важно:**
- `javaDoc` коментарите над дадените методи съдържат очакваната функционалност на задачата.
- Всички случаи, които не са експлицитно опоменати там или в условието, няма да бъдат тествани и зависят единствено на вашето въображение и преценка.
- Дадената йерархия от класове и методи не е изчерпателна и трябва да бъде доизградена от вас, прилагайки знанията от лекциите до сега.

## RentalService

Платформата за наем на превозни средства, която ще разработим е простичък клас със следната основна структура, която вие **трябва да надградите с имплементация и всичко друго, което сметнете за необходимо**:

```java
package bg.sofia.uni.fmi.mjt.vehiclerent;

import bg.sofia.uni.fmi.mjt.vehiclerent.driver.Driver;
import bg.sofia.uni.fmi.mjt.vehiclerent.exception.InvalidRentingPeriodException;
import bg.sofia.uni.fmi.mjt.vehiclerent.vehicle.Vehicle;

import java.time.LocalDateTime;

public class RentalService {

/**
* Simulates renting of the vehicle. Makes all required validations and then the provided driver "rents" the provided
* vehicle with start time @startOfRent
* @throws IllegalArgumentException if any of the passed arguments are null
* @throws VehicleAlreadyRentedException in case the provided vehicle is already rented
* @param driver the designated driver of the vehicle
* @param vehicle the chosen vehicle to be rented
* @param startOfRent the start time of the rental
*/
public void rentVehicle(Driver driver, Vehicle vehicle, LocalDateTime startOfRent) {
throw new UnsupportedOperationException("Dear Student, Remove this Exception and Implement this method");
}

/**
* This method simulates rental return - it includes validation of the arguments that throw the listed exceptions
* in case of errors. The method returns the expected total price for the rental - price for the vehicle plus
* additional tax for the driver, if it is applicable
* @param vehicle the rented vehicle
* @param endOfRent the end time of the rental
* @return
* @throws InvalidRentingPeriodException in case the endOfRent is before the start of rental, or the vehicle
* does not allow the passed period for rental, e.g. Caravans must be rented for at least a day.
*/
public double returnVehicle(Vehicle vehicle, LocalDateTime endOfRent) throws InvalidRentingPeriodException {
throw new UnsupportedOperationException("Dear Student, Remove this Exception and Implement this method");
}
}

```
## Driver
Шофьорите са репрезентирани от проста структура със следния конструктор:

```java
public Driver(AgeGroup group){}
```
където `AgeGroup` е възрастовата група на водача, представена от изброен тип `AgeGroup` със стойности:
- `JUNIOR`
- `EXPERIENCED`
- `SENIOR`

### Такса "млад шофьор"
Както забелязвате, `returnVehicle` методът връща цена за наем, която включва и такса, свързана с възрастта на шофьора. Това е честа практика при компаниите, отдаващи автомобили под наем - смята се, че по-младите и по-възрастните водачи са по-склонни към произшествия и затова те дължат по-голям депозит. В нашия случай, за простота, добавяме дневна такса, която се начислява към крайната сума за наем вместо депозит.

Таксите са както следва:
- `JUNIOR`: 10
- `EXPERIENCED`: 0
- `SENIOR`: 15

:warning: **Важно:** Таксите **не се** начисляват, ако наетото превозно средство е **колело**.

## Vehicle
Дадена е йерархия от класове, моделираща поддържаните превозни средства: като основен клас имаме `Vehicle`, който има три наследника - `Bicycle`, `Car` и `Caravan`.
Част от класа `Vehicle` изглежда по следния начин, като трябва да допълните липсващата функционалност.

:warning: **Важно:** Методите, член-данните и други детайли на класа не се изчерпват с дадените по-долу.

```java
package bg.sofia.uni.fmi.mjt.vehiclerent.vehicle;

import bg.sofia.uni.fmi.mjt.vehiclerent.driver.Driver;
import bg.sofia.uni.fmi.mjt.vehiclerent.exception.InvalidRentingPeriodException;
import bg.sofia.uni.fmi.mjt.vehiclerent.exception.VehicleAlreadyRentedException;
import bg.sofia.uni.fmi.mjt.vehiclerent.exception.VehicleNotRentedException;

import java.time.LocalDateTime;
import java.util.Objects;

public class Vehicle {

public Vehicle(String id, String model) {
this.id = id;
this.model = model;
}

/**
* Simulates rental of the vehicle. The vehicle now is considered rented by the provided driver and the start of the rental is the provided date.
* @param driver the driver that wants to rent the vehicle.
* @param startRentTime the start time of the rent
* @throws VehicleAlreadyRentedException in case the vehicle is already rented by someone else or by the same driver.
*/
public void rent(Driver driver, LocalDateTime startRentTime) throws VehicleAlreadyRentedException {
throw new UnsupportedOperationException("Dear Student, Remove this Exception and Implement this method");
}

/**
* Simulates end of rental for the vehicle - it is no longer rented by a driver.
* @param rentalEnd time of end of rental
* @throws IllegalArgumentException in case @rentalEnd is null
* @throws VehicleNotRentedException in case the vehicle is not rented at all
* @throws InvalidRentingPeriodException in case the rentalEnd is before the currently noted start date of rental or
* in case the Vehicle does not allow the passed period for rental, e.g. Caravans must be rented for at least a day
* and the driver tries to return them after an hour.
*/
public void returnBack(LocalDateTime rentalEnd) throws InvalidRentingPeriodException {
throw new UnsupportedOperationException("Dear Student, Remove this Exception and Implement this method");
}

/**
* Used to calculate potential rental price without the vehicle to be rented.
* The calculation is based on the type of the Vehicle (Car/Caravan/Bicycle).
*
* @param startOfRent the beginning of the rental
* @param endOfRent the end of the rental
* @return potential price for rent
* @throws InvalidRentingPeriodException in case the vehicle cannot be rented for that period of time or
* the period is not valid (end date is before start date)
*/
public abstract double calculateRentalPrice(LocalDateTime startOfRent, LocalDateTime endOfRent) throws InvalidRentingPeriodException;

}

```
### Видове превозни средства и цена за наем
Услугата ни предоставя възможност за наемане на три вида превозни средства - колела, коли и каравани.
Наемът и цената на всеки един от тези типове зависят от няколко условия.

:warning: **Важно:** Приемаме, че превозните средства не могат да бъде наети за по-малко от час. Всеки наем под час, струва колкото цял час.

#### Колела
- Колела могат да бъдат наемани за няколко часа или няколко дни, но не повече от седмица (6 дни, 23 часа, 59мин и 59сек; винамавайте да не паднете в overengineering pitfall, проверката е извикване на един метод).
- Колелата имат зададени цени за наем за час и за ден. Липсва наем за седмица, т.к. не могат да бъдат наемани за такъв период.

##### Конструктор:
```java
public Bicycle(String id, String model, double pricePerDay, double pricePerHour){}
```

#### Автомобили
- Автомобилите имат двигатели (представени чрез изброения тип по-долу), които имат различна **такса на ден**, която се прибавя към финалната цена за наем.
- Автомобилите имат зададени цени за наем за час, ден и седмица.
- Автомобилите имат вместимост - брой седалки и стандартна цена за една седалка - 5.

##### Конструктор:
```java
public Car(String id, String model, FuelType fuelType, int numberOfSeats, double pricePerWeek, double pricePerDay, double pricePerHour) {}
```

#### Каравани
- Караваните имат двигатели (представени чрез изброения тип по-долу), които имат различна **такса на ден**, която се прибавя към финалната цена за наем.
- Караваните имат зададени цени за наем за час, ден и седмица.
- Караваните имат вместимост - брой седалки и стандартна цена за една седалка - 5.
- Караваните имат допълнителна вместимост - брой легла и стандартна цена за едно легло - 10.

##### Конструктор:
```java
public Caravan(String id, String model, FuelType fuelType, int numberOfSeats, int numberOfBeds, double pricePerWeek, double pricePerDay, double pricePerHour) {}
```

#### enum FuelType
Стойностите на типа FuelType и техните дневни такси:
- DIESEL: 3
- PETROL: 3
- HYBRID: 1
- ELECTRICITY: 0
- HYDROGEN: 0

## Пример

```java
import bg.sofia.uni.fmi.mjt.vehiclerent.vehicle.FuelType;

public static void main(String[] args) {
RentalService rentalService = new RentalService();
LocalDateTime rentStart = LocalDateTime.of(2024, 10, 10, 0, 0, 0);
Driver experiencedDriver = new Driver(AgeGroup.EXPERIENCED);

Vehicle electricCar = new Car("1", "Tesla Model 3", FuelType.ELECTRICITY, 4, 1000, 150, 10);
rentalService.rentVehicle(experiencedDriver, electricCar, rentStart);
double priceToPay = rentalService.returnVehicle(electricCar, rentStart.plusDays(5)); // 770.0

Vehicle dieselCar = new Car("2", "Toyota Auris", FuelType.DIESEL, 4, 500, 80, 5);
rentalService.rentVehicle(experiencedDriver, dieselCar, rentStart);
priceToPay = rentalService.returnVehicle(dieselCar, rentStart.plusDays(5)); // 445.0
}
```

## Структура на пакетите

Спазвайте имената на пакетите на всички по-горе описани класове, интерфейси и конструктори, тъй като в противен случай, решението ви
няма да може да бъде автоматично тествано.

```bash
src
└─ bg/sofia/uni/fmi/mjt/vehiclerent
├─ driver/
│ ├─ Driver.java
│ └─ AgeGroup.java
├─ exception/
│ ├─ InvalidRentingPeriodException.java
│ ├─ VehicleAlreadyRentedException.java
│ └─ VehicleNotRentedException.java
├─ vehicle/
│ ├─ FuelType.java
│ ├─ Bicycle.java
│ ├─ Car.java
│ └─ Caravan.java
└─ RentalService.java
```

Желателно е да добавите собствени класове и абстракции в съответните пакети.

## :warning: Забележки

> Задачата трябва да се реши с помощта на знанията от курса до момента и допълнителните Java APIs, указани в условието.

0 comments on commit a5a392a

Please sign in to comment.