ich einen DSL mit Reflexion geschaffen, so dass wir jedes Feld, um es nicht hinzufügen müssen.
Disclamer: Dieses DSL ist extrem schwach typisiert und ich habe es nur zum Spaß gemacht. Ich glaube nicht, dass dies ein guter Ansatz in Scala ist.
scala> create an Employee where "homeAddress" is Address("a", "b") and "department" is Department("c") and that_s it
res0: Employee = Employee(a=b,null,c)
scala> create an Employee where "workAddress" is Address("w", "x") and "homeAddress" is Address("y", "z") and that_s it
res1: Employee = Employee(y=z,w=x,null)
scala> create a Customer where "address" is Address("a", "b") and "age" is 900 and that_s it
res0: Customer = Customer(a=b,900)
Das letzte Beispiel ist das Äquivalent des Schreibens:
create.a(Customer).where("address").is(Address("a", "b")).and("age").is(900).and(that_s).it
Ein Weg von DSLs in Scala zu schreiben und Klammern vermeiden und der Punkt ist dieses Muster durch folgende:
object.method(parameter).method(parameter)...
Hier ist die Quelle:
// DSL
object create {
def an(t: Employee.type) = new ModelDSL(Employee(null, null, null))
def a(t: Customer.type) = new ModelDSL(Customer(null, 0))
}
object that_s
class ModelDSL[T](model: T) {
def where(field: String): ValueDSL[ModelDSL2[T], Any] = new ValueDSL(value => {
val f = model.getClass.getDeclaredField(field)
f.setAccessible(true)
f.set(model, value)
new ModelDSL2[T](model)
})
def and(t: that_s.type) = new { def it = model }
}
class ModelDSL2[T](model: T) {
def and(field: String) = new ModelDSL(model).where(field)
def and(t: that_s.type) = new { def it = model }
}
class ValueDSL[T, V](callback: V => T) {
def is(value: V): T = callback(value)
}
// Models
case class Employee(homeAddress: Address, workAddress: Address, department: Department)
case class Customer(address: Address, age: Int)
case class Address(name: String, pincode: String) {
override def toString = name + "=" + pincode
}
case class Department(name: String) {
override def toString = name
}
Do not u Se Builder Muster in Scala. Sie sollten misstrauisch gegenüber jedem Hinweis sein, der darauf hinweist, dass Sie 'var' in scala verwenden. Es ist fast immer falsch, etwas zu tun. – Dima
@Dima yeh true ..... aber es ist eine andere Möglichkeit, emp.withAddress ("abc", "12222") zu machen. WithDepartment ("HR") – coder25
'def withAddress (Name: String, Pincode: String) = Kopie (Adresse = Adresse (Name, PIN-Code)) ' – Dima