在 Scala 中使用 DSL,假设我有这样的东西:
house {
floor {
bedroom("kids)
bedroom("master")
}
floor {
kitchen()
}
}
现在我想要的是在每个嵌套块中都有一个引用或引用封闭块上的函数。例如,效果是地板被添加到房子,卧室被添加到地板等。
目前,我以一种可怕的方式做到这一点,即拥有一个全局堆栈,该堆栈在每个嵌套级别进行更新以跟踪当前的“上下文”。另外,我当前的版本不是类型安全的,因为我可以在房子中添加一间卧室。
之前的另一个修订是
house {
floor {
bedroom("kids) +
bedroom("master")
} +
floor {
kitchen()
}
}
其中每个块返回一个小部件列表(+ 使用隐式将通用“事物”转换为“事物列表”,以便可以添加下一个“事物”)。一旦块返回,返回的小部件列表就会被添加。但我不喜欢强制使用+,因为它在很多页面上变得丑陋。
无论如何融合两者?
此方法使用可变字段在创建相关对象后设置子父关系:
/* Data classes */
class House(val floors: Seq[Floor])
class Floor(val name: String, val bedrooms: Seq[Bedroom]) { var house: House = _}
class Bedroom(val name: String) { var floor: Floor = _ }
/* Factory methods */
def house(floors: Floor*) = {
val house = new House(floors)
floors foreach (_.house = house)
house
}
def floor(name: String)(bedrooms: Bedroom*) = {
val floor = new Floor(name, bedrooms)
bedrooms foreach (_.floor = floor)
floor
}
def bedroom(name: String) = new Bedroom(name)
这允许您以简洁且类型安全的方式创建房屋结构,如下所示:
val myHouse =
house(
floor("first")(
bedroom("joe")
),
floor("second")(
bedroom("anna"),
bedroom("clara")
)
)
assert(myHouse.floors(0).house == myHouse)
assert(myHouse.floors(1).house == myHouse)
assert(myHouse.floors(0).bedrooms(0).floor == myHouse.floors(0))
assert(myHouse.floors(1).bedrooms(1).floor == myHouse.floors(1))
将常见行为分解为一些基本特征或方法应该相当容易,例如,迭代子组件以修复关系。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)