Last active
January 3, 2023 06:49
-
-
Save jonatbergn/365a1f7831642f709724cd09d1dfb301 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Milk | |
class Beans | |
class Powder | |
class Water | |
class Coffee(water: Water, powder: Powder) | |
sealed interface BrewResult { | |
class Success(val coffee: Coffee) : BrewResult | |
sealed interface Failure : BrewResult { | |
object InsufficientPowder : Failure | |
object InsufficientWater : Failure | |
object BrewerBroken : Failure | |
} | |
} | |
sealed interface GetMilkResult { | |
class Success(val milk: Milk) : GetMilkResult // don't expose success result | |
sealed interface Failure : GetMilkResult, BrewResult { | |
object Expired : Failure | |
object Empty : Failure | |
} | |
} | |
sealed interface GetBeansResult { | |
class Success(val beans: Beans) : GetBeansResult // don't expose success result | |
object Empty : GetBeansResult, BrewResult | |
} | |
sealed interface GrindBeansResult { | |
class Success(val powder: Powder) : GrindBeansResult // don't expose success result | |
sealed interface Failure : GrindBeansResult, BrewResult { | |
object GrinderBroken : Failure | |
object InsufficientBeans : Failure | |
} | |
} | |
interface Service { | |
fun getMilk(): GetMilkResult | |
fun getBeans(): GetBeansResult | |
fun grindBeans(beans: Beans): GrindBeansResult | |
fun brew(powder: Powder, water: Water, milk: Milk): BrewResult | |
} | |
interface CoffeeMachine { | |
fun brew(): BrewResult | |
} | |
class CoffeeMachineImpl( | |
private val service: Service, | |
) : CoffeeMachine { | |
override fun brew(): BrewResult { | |
val milk = when (val getMilkResult = service.getMilk()) { | |
is GetMilkResult.Success -> getMilkResult.milk | |
is GetMilkResult.Failure -> return getMilkResult | |
} | |
val beans = when (val getBeansResult = service.getBeans()) { | |
is GetBeansResult.Success -> getBeansResult.beans | |
is GetBeansResult.Empty -> return getBeansResult | |
} | |
val powder = when (val grindBeansResult = service.grindBeans(beans)) { | |
is GrindBeansResult.Success -> grindBeansResult.powder | |
is GrindBeansResult.Failure -> return grindBeansResult | |
} | |
return service.brew(powder, Water(), milk) | |
} | |
} | |
fun main(coffeeMachine: CoffeeMachine) { | |
when (val brewResult = coffeeMachine.brew()) { | |
is BrewResult.Success -> println("Enjoy your ${brewResult.coffee}") | |
BrewResult.Failure.BrewerBroken -> println("Brewer is broken") | |
BrewResult.Failure.InsufficientPowder -> println("You did not use enough powder") | |
BrewResult.Failure.InsufficientWater -> println("You did not use enough water") | |
GetBeansResult.Empty -> println("Please buy more beans first") | |
GetMilkResult.Failure.Empty -> println("Sorry, we're out of mild") | |
GetMilkResult.Failure.Expired -> println("Sorry, the milk is stale") | |
GrindBeansResult.Failure.GrinderBroken -> println("Sorry, your grinder seems to be broken") | |
GrindBeansResult.Failure.InsufficientBeans -> println("Sorry, you did not use enough beans to create powder") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment