构建树形结构域模型
如何以面向对象的方式构建具有树形结构的领域模型
引言
当我是一名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等。不要只考虑递归算法来显示树形结构,我们可以首先创建领域模型,更深入地思考和设计面向对象。




