在我的一个项目中,我们有一个非常复杂的域模型,其中包括数百种不同的域对象类型。
那是一个纯Java项目,说实话,Java在对象实例化,初始化和设置属性方面非常冗长。
突然,出现了允许用户定义和使用自己的对象模型的新要求。
所以……旅程开始了。
我们最终想到了需要某种领域语言来描述所有这些对象类型和关系。 Groovy在这里进行救援。 在本文中,我想演示使用Groovy构建器编写的简单DSL多么强大和富有表现力。
与往常一样,让我们从示例项目的POM文件开始:
4.0.0
com.example
dsl
0.0.1-SNAPSHOT
jar
UTF-8
junit
junit
4.10
org.codehaus.groovy
groovy-all
1.8.4
org.codehaus.gmaven
gmaven-plugin
1.4
1.8
compile
testCompile
org.apache.maven.plugins
maven-compiler-plugin
2.3.1
1.6
1.6
我将使用最新的Groovy版本1.8.4。 我们的域模型将包括三个类: Organization , User和Group 。 每个组织都有一个必填名称,一些用户和一些组。 每个组可以有一些用户作为成员。 非常简单,所以这里是我们的Java类。
Organization.java
package com.example;
import java.util.Collection;
public class Organization {
private String name;
private Collection< User > users = new ArrayList< User >();
private Collection< Group > groups = new ArrayList< Group >();
public String getName() {
return name;
}
public void setName( final String name ) {
this.name = name;
}
public Collection< Group > getGroups() {
return groups;
}
public void setGroups( final Collection< Group > groups ) {
this.groups = groups;
}
public Collection< User > getUsers() {
return users;
}
public void setUsers( final Collection< User > users ) {
this.users = users;
}
}
User.java
package com.example;
public class User {
private String name;
public String getName() {
return name;
}
public void setName( final String name ) {
this.name = name;
}
}
组.java
package com.example;
import java.util.Collection;
public class Group {
private String name;
private Collection< User > users = new ArrayList< User >();
public void setName( final String name ) {
this.name = name;
}
public String getName() {
return name;
}
public Collection< User > getUsers() {
return users;
}
public void setUsers( final Collection< User > users ) {
this.users = users;
}
}
现在,我们有了域模型。 让我们考虑一下普通用户如何用用户,组以及所有这些对象之间的关系来描述自己的组织。 首先,我们采用一种足以让普通用户理解的人类可读语言。 认识Groovy建设者。
package com.example.dsl.samples
class SampleOrganization {
def build() {
def builder = new ObjectGraphBuilder(
classLoader: SampleOrganization.class.classLoader,
classNameResolver: "com.example"
)
return builder.organization(
name: "Sample Organization"
) {
users = [
user(
id: "john",
name: "John"
),
user(
id: "samanta",
name: "Samanta"
),
user(
id: "tom",
name: "Tom"
)
]
groups = [
group(
id: "administrators",
name: "administrators",
users: [ john, tom ]
),
group(
id: "managers",
name: "managers",
users: [ samanta ]
)
]
}
}
}
这是一个小的测试用例,它验证了我们的域模型是否符合预期:
package com.example.dsl
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertNotNull
import org.junit.Test
import com.example.dsl.samples.SampleOrganization
class BuilderTestCase {
@Test
void 'build organization and verify users, groups' () {
def organization = new SampleOrganization().build()
assertEquals 3, organization.users.size()
assertEquals 2, organization.groups.size()
assertEquals "Sample Organization", organization.name
}
}
我在许多项目中一次又一次地使用这种简单的DSL。 它确实简化了很多复杂的对象模型的创建。
参考: JCG合作伙伴 使用Groovy的简单但功能强大的DSL Andriy Redko {devmind}博客上的Andrey Redko
翻译自: https://www.javacodegeeks.com/2012/03/simple-but-powerful-dsl-using-groovy.html