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
5 changes: 5 additions & 0 deletions src/main/kotlin/ru/otus/cars/Car.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ interface Car : CarInput {
*/
val carOutput: CarOutput

/**
* Топливная горловина
*/
val tankMouth: TankMouth

/**
* Получить оборудование
*/
Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/ru/otus/cars/CarFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ object Togliatti : CarFactory {
println("Запил ${Vaz2107.MODEL} в Тольятти...")
val vaz = Vaz2107.build(plates)
println("Проверяем тачку...")
Vaz2107.test(vaz)
Vaz2107.test(vaz as Vaz2107)
vaz.drdrdrdrdr()
return vaz
}
Expand All @@ -27,7 +27,7 @@ object Togliatti : CarFactory {
println("Запил ${Vaz2108.MODEL} в Тольятти...")
val vaz = Vaz2108.build(plates)
println("Сход-развал...")
Vaz2108.alignWheels(vaz)
Vaz2108.alignWheels(vaz as Vaz2108)
vaz.zhzhzhzh()
return vaz
}
Expand Down
1 change: 1 addition & 0 deletions src/main/kotlin/ru/otus/cars/CarOutput.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ interface CarOutput {
* Скажи текущую скорость
*/
fun getCurrentSpeed(): Int
fun getTankContents(): Int
}
30 changes: 30 additions & 0 deletions src/main/kotlin/ru/otus/cars/FuelStation.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package ru.otus.cars

interface FuelStationInterface {
fun refuel(tankMouth: TankMouth, volume: Int): RefuelResult
}

enum class RefuelResult {
DONE,
ERROR
}

class FuelStation : FuelStationInterface {
override fun refuel(tankMouth: TankMouth, volume: Int): RefuelResult {
try {
tankMouth.open()
when (tankMouth) {
is TankMouth.LpgTankMouth -> tankMouth.fuelLpg(volume)
is TankMouth.PetrolTankMouth -> tankMouth.fuelPetrol(volume)
}
tankMouth.close()
return RefuelResult.DONE
} catch (e: TankMouthException) {
println(e.message)
return RefuelResult.ERROR
} catch (e: Throwable) {
println("Что-то не так. Прекратили все работы.")
return RefuelResult.ERROR
}
}
}
44 changes: 44 additions & 0 deletions src/main/kotlin/ru/otus/cars/Tank.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package ru.otus.cars

open class Tank(val initialVolume: Int) : TankInterface {

private var volume: Int = initialVolume
get() {
if (field <= 0) throw Exception("Tank volume should be more than zero")
return field
}
set(value) {
if (value <= 0) throw Exception("Tank volume should be more than zero")
field = value
}

private var fuelBalance: Int = 0

override fun getContents(): Int = fuelBalance

override fun receiveFuel(liters: Int) {
when {
liters < 0 -> throw TankException("Liters can't be negative")
liters + fuelBalance > volume -> {
fuelBalance = volume
throw TankException("Tank full")
}

liters + fuelBalance <= volume -> fuelBalance += liters
}
}

override fun toString(): String {
return "Tank(volume=$volume, fuelBalance=$fuelBalance)"
}


}


interface TankInterface {
fun getContents(): Int
fun receiveFuel(liters: Int)
}

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


interface TankMouthInterface {
fun open()
fun close()
}

sealed class TankMouth : TankMouthInterface {
protected lateinit var tank: TankInterface

protected fun buildWithTank(tank: TankInterface): TankMouth {
this.tank = tank
return this
}

protected fun receiveFuel(liters: Int) {
try {
tank.receiveFuel(liters)
} catch (e: TankException) {
throw TankMouthException(e.message ?: "Tank mouth error")
}
}

fun getContents() : Int = tank.getContents()

enum class TankMouthState { OPEN, CLOSED }

private var state: TankMouthState = TankMouthState.CLOSED
override fun open() {
state = TankMouthState.OPEN
}

override fun close() {
state = TankMouthState.CLOSED
}

class PetrolTankMouth private constructor(): TankMouth() {
companion object {
fun build(tank: TankInterface) : TankMouth {
return PetrolTankMouth().buildWithTank(tank)
}
}

fun fuelPetrol(liters: Int) = super.receiveFuel(liters)

override fun toString(): String {
return "PetrolTankMouth($tank)"
}
}

class LpgTankMouth private constructor(): TankMouth() {
companion object {
fun build(tank: TankInterface) : TankMouth {
return LpgTankMouth().buildWithTank(tank)
}
}
fun fuelLpg(liters: Int) = super.receiveFuel(liters)

override fun toString(): String {
return "LpgTankMouth($tank)"
}
}
}



class TankMouthException(message: String) : Exception(message)
9 changes: 9 additions & 0 deletions src/main/kotlin/ru/otus/cars/Taz.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,19 @@ object Taz: Car {
override val carOutput: CarOutput
get() = throw NotImplementedError("Приборов нет")


class TazTank: Tank(initialVolume = 20) {
override fun receiveFuel(liters: Int) {
throw NotImplementedError("Bang!!")
}
}

/**
* Получить оборудование
*/
override fun getEquipment(): String = "Крыса"
override val tankMouth: TankMouth
get() = TankMouth.PetrolTankMouth.build(TazTank())

/**
* Руль вправо на [degrees] градусов
Expand Down
12 changes: 10 additions & 2 deletions src/main/kotlin/ru/otus/cars/Vaz2107.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ class Vaz2107 private constructor(color: String) : VazPlatform(color) {
}
}

override fun build(plates: Car.Plates): Vaz2107 = Vaz2107("Зеленый").apply {
override fun build(plates: Car.Plates): Car = Vaz2107("Зеленый").apply {
this.engine = getRandomEngine()
this.plates = plates
this.tankMouth = TankMouth.LpgTankMouth.build(Tank(50))
}

/**
Expand All @@ -40,6 +41,9 @@ class Vaz2107 private constructor(color: String) : VazPlatform(color) {
override lateinit var engine: VazEngine
private set

override lateinit var tankMouth: TankMouth
private set

/**
* Семерка едет так
*/
Expand All @@ -59,7 +63,7 @@ class Vaz2107 private constructor(color: String) : VazPlatform(color) {

// Выводим состояние машины
override fun toString(): String {
return "Vaz2107(plates=$plates, wheelAngle=$wheelAngle, currentSpeed=$currentSpeed)"
return "Vaz2107(plates=$plates, wheelAngle=$wheelAngle, currentSpeed=$currentSpeed, tankMouth=$tankMouth)"
}

/**
Expand All @@ -74,5 +78,9 @@ class Vaz2107 private constructor(color: String) : VazPlatform(color) {
override fun getCurrentSpeed(): Int {
return this@Vaz2107.currentSpeed
}

override fun getTankContents(): Int {
return this@Vaz2107.tankMouth.getContents()
}
}
}
12 changes: 10 additions & 2 deletions src/main/kotlin/ru/otus/cars/Vaz2108.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ class Vaz2108 private constructor(color: String) : VazPlatform(color) {
}
}

override fun build(plates: Car.Plates): Vaz2108 = Vaz2108("Красный").apply {
override fun build(plates: Car.Plates): Car = Vaz2108("Красный").apply {
this.engine = getRandomEngine()
this.plates = plates
this.tankMouth = TankMouth.PetrolTankMouth.build(Tank(65))
}

fun alignWheels(vaz2108: Vaz2108) {
Expand All @@ -38,6 +39,9 @@ class Vaz2108 private constructor(color: String) : VazPlatform(color) {
override lateinit var engine: VazEngine
private set

override lateinit var tankMouth: TankMouth
private set

/**
* Восьмерка едет так
*/
Expand All @@ -63,7 +67,7 @@ class Vaz2108 private constructor(color: String) : VazPlatform(color) {

// Выводим состояние машины
override fun toString(): String {
return "Vaz2108(plates=$plates, wheelAngle=$wheelAngle, currentSpeed=$currentSpeed)"
return "Vaz2108(plates=$plates, wheelAngle=$wheelAngle, currentSpeed=$currentSpeed, tankMouth=$tankMouth)"
}

/**
Expand All @@ -78,5 +82,9 @@ class Vaz2108 private constructor(color: String) : VazPlatform(color) {
override fun getCurrentSpeed(): Int {
return this@Vaz2108.currentSpeed
}

override fun getTankContents(): Int {
return this@Vaz2108.tankMouth.getContents()
}
}
}
29 changes: 26 additions & 3 deletions src/main/kotlin/ru/otus/cars/main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ fun main() {
techChecks()
println("\n===> Taz...")
println(Taz.color)
refuelCars()
}

fun driveCars() {
Expand All @@ -31,7 +32,7 @@ fun driveCars() {

fun innerNestedCheck() {
val vaz = Vaz2107.build(Car.Plates("123", 77))
val output = vaz.VazOutput() // Создаем новый объект ИЗ ЭКЗЕМПЛЯРА МАШИНЫ
val output = (vaz as Vaz2107).VazOutput() // Создаем новый объект ИЗ ЭКЗЕМПЛЯРА МАШИНЫ

println("Скорость до проверки: ${output.getCurrentSpeed()}") // Выводит 0
Vaz2107.test(vaz) // Газуем...
Expand Down Expand Up @@ -78,8 +79,8 @@ fun techChecks() {
val vaz1 = Vaz2107.build(Car.Plates("123", 77))
val vaz2 = Vaz2108.build(Car.Plates("321", 78))

repairEngine(vaz1)
repairEngine(vaz2)
repairEngine(vaz1 as VazPlatform)
repairEngine(vaz2 as VazPlatform)
}

fun repairEngine(car: VazPlatform) {
Expand All @@ -90,4 +91,26 @@ fun repairEngine(car: VazPlatform) {
is VazEngine.LADA_2107 -> println("Чистка карбюратора у двигателя объемом ${car.engine.volume} куб.см у машины $car")
is VazEngine.SAMARA_2108 -> println("Угол зажигания у двигателя объемом ${car.engine.volume} куб.см у машины $car")
}
}

fun refuelCars() {
val cars: List<Car> = listOf(
Vaz2107.build(Car.Plates("123", 77)),
Vaz2108.build(Car.Plates("321", 78)),
Taz
)

val station = FuelStation()

for (car in cars) {
println("Собираемся заправить $car, Кол-во топлива: ${car.tankMouth.getContents()}")
val refuelResult = station.refuel(car.tankMouth, 10)
println("Результат заправки $refuelResult, Кол-во топлива: ${car.tankMouth.getContents()}, Машина: $car")
}

for (car in cars) {
println("Собираемся заправить $car, Кол-во топлива: ${car.tankMouth.getContents()}")
val refuelResult = station.refuel(car.tankMouth, 15)
println("Результат заправки $refuelResult, Кол-во топлива: ${car.tankMouth.getContents()}, Машина: $car")
}
}