构建树形结构域模型
如何以面向对象的方式构建具有树形结构的领域模型
引言
当我是一名MIS工程师时,我维护着一个调度系统。许多任务由自动调度系统控制,请参阅下面的示例XML文件:由于XML文件是树形结构,因此可以清晰地描述任务流程。
<Schedule>
<JobGroup>
<BatchJob id="1" name="job1"></BatchJob>
<BatchJob id="2" name="job2"></BatchJob>
<JobGroup id="3" name="job3">
<BatchJob id="4" name="job3-1"></BatchJob>
<BatchJob id="5" name="job3-2"></BatchJob>
<JobGroup id="6" name="job3-3">
<BatchJob id="7" name="job3-3-1"></BatchJob>
</JobGroup>
</JobGroup>
</JobGroup>
</Schedule>
但是,我们如何使用编程语言构建领域模型?这是一个系统设计问题。
背景
代码是用Java编写的,并使用JavaSE 5编译。您需要了解XML、UML和设计模式的概念。
Using the Code
如何构建树形结构领域模型?我使用组合设计模式!

考虑以下源代码
Job
是一个 abstract
类,是 BatchJob
和 JobGroup
的父类
package org.schedulemanager.demo.model;
import java.util.ArrayList;
import java.util.List;
public abstract class Job {
protected String id;
protected String name;
protected String circle;
protected String type;
public final static String BATCHJOB = "BATCHJOB";
public final static String JOBGROUP = "JOBGROUP";
public final static String DAILY = "DAILY";
public final static String WEEKLY = "WEEKLY";
public final static String MONTHLY = "MONTHLY";
public Job(String id) {
this.id = id ;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public abstract void addJob(Job job);
public abstract List<job> getJobList();
}
JobGroup
是一个不执行任何操作的任务,它是 Job
的子类,但它也是 Job
的容器。 JobGroup
具有一个循环字段来设置执行时间。
package org.schedulemanager.demo.model;
import java.util.ArrayList;
import java.util.List;
public class JobGroup extends Job {
private List<job> jobList;
public JobGroup(String id, String name) {
super(id);
this.type = JOBGROUP;
this.name = name;
jobList = new ArrayList<job>();
}
public JobGroup(String id, String name, String circle) {
this(id, name);
this.circle = circle;
}
public List<job> getJobList() {
return jobList;
}
public void addJob(Job job){
if(job!=null && job.getId()!=null){
jobList.add(job);
}
}
public String getCircle() {
return circle;
}
public void setCircle(String circle) {
this.circle = circle;
}
public boolean removeJob(String id){
boolean result = false;
for(int i=0;i<joblist.size();i++)
{ job="jobList.get(i);" jobid="job.getId();" result="true;"
BatchJob
是一个执行特定操作的任务
package org.schedulemanager.demo.model;
import java.util.List;
public class BatchJob extends Job {
public BatchJob(String id, String name) {
super(id);
this.type = BATCHJOB;
this.name = name;
}
public void addJob(Job job) {
System.err.println("BatchJob can not addJob!");
}
public List<job> getJobList() {
return null;
}
public String toString() {
return "id:" + id
+ ",name:" + name
+ ",type:" + type ;
}
}
我创建了一个 CommandLineView
来在控制台上显示任务流程
package org.schedulemanager.demo.view;
import java.util.List;
import org.schedulemanager.demo.model.Job;
public class CommandLineView {
private Job job;
public Job getJob() {
return job;
}
public void setJob(Job job) {
this.job = job;
}
public void printAllJobs() {
printAllJobs(job, 0);
}
public void printAllJobs(Job job , int depth) {
List<Job> jobList = job.getJobList();
if(jobList!=null && jobList.size()>0){
for(int i=0;i<jobList.size();i++){
printDepth(depth);
Job subJob = jobList.get(i);
if(subJob.getType().equalsIgnoreCase
(Job.BATCHJOB)){
System.out.print("-");
System.out.println(subJob);
}else if(subJob.getType().equalsIgnoreCase
(Job.JOBGROUP)){
System.out.print("+");
System.out.println(subJob);
printAllJobs(subJob, depth + 1);
}
}//end for
}
}
public void printDepth(int depth) {
for(int i=0;i<depth;i++){
System.out.print("\t");
}
}
}
管理器负责组装模型和视图
package org.schedulemanager.demo;
import org.schedulemanager.demo.model.BatchJob;
import org.schedulemanager.demo.model.JobGroup;
import org.schedulemanager.demo.model.Job;
import org.schedulemanager.demo.view.CommandLineView;
public class Manager {
private Job rootJob;
public Manager() {
initJobs();
}
public void initJobs(){
rootJob = new JobGroup("0", "rootJob",Job.DAILY);
Job job1 = new BatchJob("1","job1");
Job job2 = new BatchJob("2","job2");
Job job3 = new JobGroup("3","job3",Job.DAILY);
Job job4 = new BatchJob("4","job3-1");
Job job5 = new BatchJob("5","job3-2");
Job job6 = new JobGroup("6","job3-3",Job.DAILY);
Job job7 = new BatchJob("7","job3-3-1");
Job job8 = new BatchJob("8","job4");
Job job9 = new BatchJob("9","job5");
job6.addJob(job7);
job3.addJob(job4);
job3.addJob(job5);
job3.addJob(job6);
job3.addJob(job8);
rootJob.addJob(job1);
rootJob.addJob(job2);
rootJob.addJob(job3);
rootJob.addJob(job9);
}
public void run(){
CommandLineView view = new CommandLineView();
view.setJob(rootJob);
view.printAllJobs();
}
public static void main(String[] args) {
Manager manager = new Manager();
manager.run();
}
}
运行结果如下所示

您还可以使用领域模型轻松创建其他视图(Web、GUI 等)。
关注点
考虑任务依赖性!批处理作业是按顺序执行的。因此,任务依赖性是一个重要问题。我们的树形领域模型具有可扩展性,我们可以添加作业类 dependencyList
字段。 附加的UML如下所示

摘要
思考这个树形结构领域模型,它可以应用于许多实践,例如:项目管理工具、文件系统、树形GUI等。不要只考虑递归算法来显示树形结构,我们可以首先创建领域模型,更深入地思考和设计面向对象。