Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/kotlin/ru/otus/cars/Car.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ interface Car : CarInput {
* Внутренний статический класс - номерой знак
*/
data class Plates(val number: String, val region: Int)

fun fillTank(fuelType: String, volume: Int): Int
}
10 changes: 9 additions & 1 deletion src/main/kotlin/ru/otus/cars/CarOutput.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ package ru.otus.cars
*/
interface CarOutput {
/**
* Скажи текущую скорость
* Скажи текущее состояние
*/

// Текущая скорость
fun getCurrentSpeed(): Int

// Уровень топлива в баке
fun getFuelIndicator(): Int

// Общая информация о баке
fun getTankInfo(): String
}
3 changes: 3 additions & 0 deletions src/main/kotlin/ru/otus/cars/ExploseanException.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ru.otus.cars

class ExplosionException(message: String) : Exception(message)
36 changes: 36 additions & 0 deletions src/main/kotlin/ru/otus/cars/GasStation.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package ru.otus.cars

/**
* Заправочная станция
*/
object GasStation {
fun refuel(car: Car, fuelType: String, volume: Int) {
println("Заправляем машину ${car::class.simpleName} ($volume л. $fuelType)...")

// Проверка на отрицательные значения и 0
if (volume < 0) {
println("Ошибка: Нельзя заправить $volume топлива")
return
}

if (volume == 0) {
println("Заправка $volume литров - ничего не делаем")
return
}

try {
val filled = car.fillTank(fuelType, volume)
if (filled > 0) {
println("Успешно заправлено $filled литров $fuelType")
} else {
println("Бак полный, заправка не требуется")
}
} catch (e: ExplosionException) {
println("${e.message}")
} catch (e: IllegalArgumentException) {
println("Проблема: ${e.message}")
} catch (e: Exception) {
println("Неизвестная ошибка: ${e.message}")
}
}
}
11 changes: 11 additions & 0 deletions src/main/kotlin/ru/otus/cars/Tank.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ru.otus.cars

/**
* Часть топливной системы: Бак
*/
interface Tank {
val capacity: Int
var currentFuel: Int
fun fill(volume: Int): Int
fun getCurrentFuelVolume(): Int
}
44 changes: 44 additions & 0 deletions src/main/kotlin/ru/otus/cars/TankMouth.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package ru.otus.cars

/**
* Часть топливной системы: Горловина
*/
sealed class TankMouth {
abstract val fuelType: String
abstract fun canAccept(fuel: String): Boolean

// Разные методы заправки для разных типов горловин
abstract fun refuel(tank: Tank, volume: Int): Int

// Горловина для бензина
data class GasolineMouth(override val fuelType: String = "Бензин") : TankMouth() {
override fun canAccept(fuel: String): Boolean = fuel == "Бензин"

override fun refuel(tank: Tank, volume: Int): Int {
println("Заправка бензином через специальную горловину для бензина...")
return tank.fill(volume)
}
}

// Горловина для газа
data class GasMouth(override val fuelType: String = "Газ") : TankMouth() {
override fun canAccept(fuel: String): Boolean = fuel == "Газ"

override fun refuel(tank: Tank, volume: Int): Int {
println("Заправка газом через газовую горловину...")
return tank.fill(volume)
}
}

// Горловина для ТАЗа (взрывающаяся)
object TazMouth : TankMouth() {
override val fuelType: String = "Любой тип топлива"

override fun canAccept(fuel: String): Boolean = true

override fun refuel(tank: Tank, volume: Int): Int {
println("Попытка заправки ТАЗа...")
throw ExplosionException("БА-БАХ! ТАЗ взорвался при заправке!")
}
}
}
25 changes: 25 additions & 0 deletions src/main/kotlin/ru/otus/cars/Taz.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,29 @@ object Taz: Car {
override fun wheelToLeft(degrees: Int) {
throw NotImplementedError("Руля нет")
}

override fun fillTank(fuelType: String, volume: Int): Int {
// Проверяем можно ли заправить через горловину
if (!tazTankMouth.canAccept(fuelType)) {
throw IllegalArgumentException("Нельзя заправить этот тип топлива")
}
// Используем горловину для заправки (она взорвется)
return tazTankMouth.refuel(tazTank, volume)
}

private val tazTank = TazTank
private val tazTankMouth = TankMouth.TazMouth

private object TazTank : Tank {
override val capacity: Int = 0
override var currentFuel: Int = 0

override fun fill(volume: Int): Int {
// Этот метод никогда не вызовется, т.к. горловина взорвется раньше
currentFuel += volume
return volume
}

override fun getCurrentFuelVolume(): Int = currentFuel
}
}
8 changes: 8 additions & 0 deletions src/main/kotlin/ru/otus/cars/Vaz2107.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ class Vaz2107 private constructor(color: String) : VazPlatform(color) {
else -> VazEngine.LADA_2107(1600)
}
}
private fun createTank(): Tank = VazTank(40)
private fun createTankMouth(): TankMouth = TankMouth.GasMouth()

override fun build(plates: Car.Plates): Vaz2107 = Vaz2107("Зеленый").apply {
this.engine = getRandomEngine()
this.plates = plates
setFuelTank(createTank())
setTankMouth(createTankMouth())
}

/**
Expand Down Expand Up @@ -74,5 +78,9 @@ class Vaz2107 private constructor(color: String) : VazPlatform(color) {
override fun getCurrentSpeed(): Int {
return [email protected]
}

override fun getFuelIndicator(): Int = [email protected]()

override fun getTankInfo(): String = "${[email protected]()} л"
}
}
8 changes: 8 additions & 0 deletions src/main/kotlin/ru/otus/cars/Vaz2108.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ class Vaz2108 private constructor(color: String) : VazPlatform(color) {
else -> VazEngine.SAMARA_2108(1500)
}
}
private fun createTank(): Tank = VazTank(40)
private fun createTankMouth(): TankMouth = TankMouth.GasolineMouth()

override fun build(plates: Car.Plates): Vaz2108 = Vaz2108("Красный").apply {
this.engine = getRandomEngine()
this.plates = plates
setFuelTank(createTank())
setTankMouth(createTankMouth())
}

fun alignWheels(vaz2108: Vaz2108) {
Expand Down Expand Up @@ -53,6 +57,7 @@ class Vaz2108 private constructor(color: String) : VazPlatform(color) {
}

private var currentSpeed: Int = 0 // Скока жмёт
private var currentFuelVolume: Int = 0 // Сколько бензина в баке

/**
* Доступно сборщику
Expand All @@ -78,5 +83,8 @@ class Vaz2108 private constructor(color: String) : VazPlatform(color) {
override fun getCurrentSpeed(): Int {
return [email protected]
}

override fun getFuelIndicator(): Int = [email protected]()
override fun getTankInfo(): String = "${[email protected]()} л"
}
}
54 changes: 53 additions & 1 deletion src/main/kotlin/ru/otus/cars/VazPlatform.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ru.otus.cars

import kotlin.system.exitProcess

abstract class VazPlatform(override val color: String) : Car {
// Положение руля. Доступно только внутри класса и наследникам
protected var wheelAngle: Int = 0 // Положение руля
Expand All @@ -9,8 +11,38 @@ abstract class VazPlatform(override val color: String) : Car {
// Реализация интерфейса CarInput
override fun wheelToLeft(degrees: Int) { wheelAngle -= degrees }

// Скрываем реализацию бака и горловину, используем только внутри класса
private lateinit var fuelTank: Tank
private lateinit var tankMouth: TankMouth

protected fun setFuelTank(tank: Tank) {
this.fuelTank = tank
}

protected fun setTankMouth(mouth: TankMouth) {
this.tankMouth = mouth
}

override fun fillTank(fuelType: String, volume: Int): Int {
if (!tankMouth.canAccept(fuelType)) {
throw IllegalArgumentException("Нельзя заправить $fuelType")
}
// В зависимости от типа горловины!
return tankMouth.refuel(fuelTank, volume)
}

// Метод для получения уровня топлива (через CarOutput)
protected fun getFuelLevel(): Int {
return fuelTank.getCurrentFuelVolume()
}

// Метод для получения вместимости бака
protected fun getTankCapacity(): Int {
return fuelTank.capacity
}

// Получить оборудование
override fun getEquipment(): String = "Кузов, колеса, движок"
override fun getEquipment(): String = "Кузов, колеса, движок, топливная система"

// Абстрактное свойство двигателя
abstract val engine: VazEngine
Expand All @@ -23,4 +55,24 @@ sealed class VazEngine {

data class LADA_2107(override val volume: Int) : VazEngine()
data class SAMARA_2108(override val volume: Int) : VazEngine()
}
open class VazTank(override val capacity: Int = 40) : Tank {
override var currentFuel: Int = 0

override fun fill(volume: Int): Int {
if (volume < 0) {
throw IllegalArgumentException("Нельзя заправить отрицательное количество топлива")
}

val availableSpace = capacity - currentFuel
val actualFill = minOf(volume, availableSpace)

if (actualFill > 0) {
currentFuel += actualFill
}

return actualFill
}

override fun getCurrentFuelVolume(): Int = currentFuel
}
Loading