Skip to content

Instantly share code, notes, and snippets.

@danclien
Last active December 26, 2015 04:39
Show Gist options
  • Save danclien/7094990 to your computer and use it in GitHub Desktop.
Save danclien/7094990 to your computer and use it in GitHub Desktop.
Attempting to do dependency injection using the Cake Pattern – `Car` has an `Engine`. Choice of two different engines that's wired with a car under "Example usage" at the bottom.
/*
Dependency injection test using the Cake Pattern
Notes:
* `Component` wrapper traits
* Allows multiple `Component`s to be composed together
* Each of these classes must have their own `Component` trait:
* Dependency interface
* Dependency implementation
* Dependent implementation (class using a dependency)
* `Component` dependency instance
* Each dependency interface component must declare an abstract instance of the dependency interface
* A container singleton object wires up all the dependencies
*/
object CakePatternTest {
/***** Dependency interface *****/
trait EngineComponent {
val engine: Engine
trait Engine {
def start: Unit
}
}
/***** Dependency implementations *****/
trait FourCylinderEngineComponent extends EngineComponent {
class FourCylinderEngine extends Engine {
def start: Unit = println("FourCylinderEngine.start: vroom")
}
}
trait EightCylinderEngineComponent extends EngineComponent {
class EightCylinderEngine extends Engine {
def start: Unit = println("EightCylinderEngine.start: VROOM")
}
}
/***** Dependent implementation *****/
trait CarComponent {
this: EngineComponent => // Makes CarComponent depend on an EngineComponent
class Car {
def turnKey: Unit = {
println("Attempting to start the car...")
engine.start
}
}
}
/***** Containers *****/
object FourCylinderContainer extends CarComponent with FourCylinderEngineComponent {
val engine = new FourCylinderEngine
val car = new Car
}
object EightCylinderContainer extends EightCylinderEngineComponent with CarComponent {
val engine = new EightCylinderEngine
val car = new Car
}
/***** Example usage *****/
val fourCylinderCar = FourCylinderContainer.car
fourCylinderCar.turnKey
val eightCylinderCar = EightCylinderContainer.car
eightCylinderCar.turnKey
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment