In short:
- Singleton objects act as modules
- Classes act as templates for modules
- Classes can be decomposed into traits
object Example1 {
trait FoodCategories {
case class FoodCategory(name: String, foods: List[Food])
def allCategories: List[FoodCategory]
}
trait SimpleFoods {
object Pear extends Food("Pear")
def allFoods = List(Apple, Pear)
def allCategories = Nil
}
trait SimpleRecipes {
this: SimpleFoods =>
object FruitSalad extends Recipe(
"fruit salad",
List(Apple, Pear),
"Mix all"
)
}
abstract class Browser {
val database: Database
def recipesUsing(food: Food) = {
database.allRecipes.filter(
recipe => recipe.ingredients.contains(food)
)
}
def displayCategory(category: database.FoodCategory): Unit = {
println(category)
}
}
abstract class Database extends FoodCategories {
def allFoods: List[Food]
def allRecipes: List[Recipe]
def foodNamed(name: String) = allFoods.find(f => f.name == name)
}
abstract class Food(val name: String) {
override def toString = name
}
class Recipe(
val name: String,
val ingredients: List[Food],
val instructions: String
) {
override def toString = name
}
object Apple extends Food("Apple")
object Orange extends Food("Orange")
object Cream extends Food("Cream")
object Sugar extends Food("Sugar")
object FruitSalad extends Recipe("fruit salad", List(Apple, Orange, Cream, Sugar),
"Stir it all together")
object SimpleDatabase extends Database {
override def allFoods = List(Apple, Orange, Cream, Sugar)
override def allRecipes: List[Recipe] = List(FruitSalad)
private val categories = List(
FoodCategory("fruits", List(Apple, Orange)),
FoodCategory("misc", List(Cream, Sugar))
)
override def allCategories = categories
}
object SimpleBrowser extends Browser {
override val database = SimpleDatabase
}
object StudentDatabase extends Database {
object FrozenFood extends Food("FrozenFood")
object HeatItUp extends Recipe(
"heat it up",
List(FrozenFood),
"Microwave the food for 10 min"
)
override def allFoods: List[Food] = List(FrozenFood)
override def allCategories: List[StudentDatabase.FoodCategory] = List(FoodCategory("edible",allFoods))
override def allRecipes: List[Recipe] = List(HeatItUp)
}
object StudentBrowser extends Browser {
override val database: Database = StudentDatabase
}
}
object Test {
import Example1._
val apple: Option[Food] = SimpleDatabase.foodNamed("Apple")
SimpleBrowser.recipesUsing(apple.get)
val frozen = StudentDatabase.foodNamed("FrozenFood")
StudentBrowser.recipesUsing(frozen.get)
val db: Database = SimpleDatabase
object browser extends Browser {
val database: db.type = db
}
for(recipe <- browser.recipesUsing(apple.get)) println(recipe)
for(cat <- db.allCategories) browser.displayCategory(cat)
}
0 comments:
Post a Comment