65.9K
CodeProject 正在变化。 阅读更多。
Home

构建树形结构域模型

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (3投票s)

2008年12月12日

CPOL

1分钟阅读

viewsIcon

36287

downloadIcon

243

如何以面向对象的方式构建具有树形结构的领域模型

引言

当我是一名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

如何构建树形结构领域模型?我使用组合设计模式!

treemodeluml

考虑以下源代码

Job 是一个 abstract 类,是 BatchJobJobGroup 的父类

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();
	}
}

运行结果如下所示

treemodeluml_cmd

您还可以使用领域模型轻松创建其他视图(Web、GUI 等)。

关注点

考虑任务依赖性!批处理作业是按顺序执行的。因此,任务依赖性是一个重要问题。我们的树形领域模型具有可扩展性,我们可以添加作业类 dependencyList 字段。 附加的UML如下所示

treemodeljob

摘要

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

© . All rights reserved.