java – 用于管理任务组的设计模式
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 用于管理任务组的设计模式,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4845字,纯文字阅读大概需要7分钟。
内容图文
我有一个处理Task对象的系统,现在我想进行一些基准测试实验.具体来说,我将创建许多(~100)Task对象,每个对象属于一组任务,我想在整个任务组上运行系统.我想要一个能够轻松创建新任务并将其与群组相关联的设计(轻松实现基准套件多样化).只有少数几个组,因此一些每组基础设施是可以接受的.
任务可以包含任意对象,因此我无法从“数据”文件类型(如JSON)加载它们 – 只有Java代码足以创建任务.此外,为了可维护性,我想在单独的Java文件中创建每个Task:
// SolveHaltingProblem.java
public class SolveHaltingProblem {
static Task getTask() {
Task task = new Task();
task.setName("SolveHaltingProblem");
... // Create task
return task;
}
static String getGroup() {
return "impossible-tasks";
}
}
然后,收集任务组应该很容易:
List<Task> tasks = gatherTasksInGroup("impossible-tasks");
没有愚蠢和容易出错的东西,如:
List<Task> gatherTasksInGroup(String groupName) {
List<Task> list = new ArrayList<>();
if (groupName.equals("impossible-tasks")) {
list.add(SolveHaltingProblem.getTask());
list.add(SomeOtherHardProblem.getTask());
...
} else if (...) {
... // ~100 more lines
}
return list;
}
我提供上述代码只是为了帮助传达我的需求,而设计细节并非一成不变.也许最好让SolveHaltingProblem扩展ImpossibleTaskGroup,扩展TaskGroup ……
我知道类在其他类中注册自己的模式(有这个名称吗?),但我不认为这种模式适用于此,因为我没有创建SolveHaltingProblem的实例,因此我不能强制运行SolveHaltingProblem的任何静态初始值设定项.我也尝试过搜索StackOverflow类似的问题,但我发现这个问题很难描述;如果这是重复,我道歉.
总而言之,我的问题是:如何管理任务组,以便轻松添加新任务并将其与组关联?一个好的设计将具有以下属性(从最重要到最不重要的排序):
>每个任务都在单独的文件中创建
>添加新任务并将其与组关联仅涉及添加/更改一个文件
>我们只为请求的组构造Task对象
>通过对现有组进行微小修改的复制/粘贴基础结构,“创建新组”非常简单
>我们不会迭代类路径中的所有类,也不会迭代文件系统中的文件
解决方法:
一种解决方案是使用Composite Pattern,其中接口是Task,终端类是ExecutableTask(问题中的Task是什么),复合类是TaskGroup.示例实现如下:
public interface Task {
public void execute();
}
public class ExecutableTask implements Task {
@Override
public void execute() {
// Do some work
}
}
public class TaskGroup implements Task {
private final String name;
private final List<Task> tasks = new ArrayList<>();
public TaskGroup(String name) {
this.name = name;
}
@Override
public void execute() {
for (Task task: tasks) {
task.execute();
}
}
public void addTask(Task task) {
tasks.add(task);
}
public String getName() {
return name;
}
}
这将允许您以与执行单个任务完全相同的方式执行任务组.例如,假设我们有一些方法,基准测试,对任务进行基准测试,我们可以提供ExecutableTask(单个任务)或TaskGroup:
public void benchmarkTask(Task task) {
// Record start time
task.execute();
// Record completion time
}
// Execute single task
Task oneOffTask = new ExecutableTask();
benchmarkTask(oneOffTask);
// Execute a group of tasks
TaskGroup taskGroup = new TaskGroup("someGroup");
taskGroup.addTask(new ExecutableTask());
taskGroup.addTask(new ExecutableTask());
benchmarkTask(taskGroup);
也可以通过创建匹配可以完成的不同任务的各种Task实现(或扩展ExecutableTask)来扩展此模式.例如,假设我们有两种不同类型的任务:颜色任务和定时任务:
public class ColorTask implements Task {
private final String color;
public ColorTask(String color) {
this.color = color;
}
@Override
public void execute() {
System.out.println("Executed task with color " + color);
}
}
public class TimedTask implements Task {
private final long seconds;
public TimedTask(int seconds) {
this.seconds = seconds * 1000;
}
@Override
public void execute() {
Thread.sleep(seconds * 1000);
System.out.println("Executed timed task for " + seconds + " seconds");
}
}
然后,您可以创建一个不同的Task实现的TaskGroup,并在没有任何特定于类型的逻辑的情况下运行它们:
TaskGroup group = new TaskGroup("differentTasksGroup");
group.addTask(new ColorTask("red"));
group.addTask(new TimedTask(2));
group.execute();
这将导致以下输出:
Executed task with color red
Executed timed task for 2 seconds
加载新任务
使用此复合结构,您可以使用Java提供的Service Provider Interface (SPI).虽然我不在这里详细介绍(链接页面包含有关如何设置和注册服务的丰富知识),但一般的想法是您可以将Task接口充当服务接口,然后加载各种任务您注册为服务.例如:
public class TaskServiceMain {
public static void main(String[] args) {
TaskGroup rootGroup = new TaskGroup("root");
ServiceLoader serviceLoader = ServiceLoader.load(Task.class);
for (Task task: serviceLoader) {
rootGroup.addTask(task);
}
// Execute all of the tasks
rootGroup.execute();
}
}
使用复合层次结构的根(任务接口)作为服务接口可能很奇怪,因此创建新的服务接口可能是个好主意.例如,可以创建一个新接口,它只是作为不添加新功能的标记接口:
public interface ServiceTask extends Task {}
然后,服务加载逻辑变为:
public class TaskServiceMain {
public static void main(String[] args) {
TaskGroup rootGroup = new TaskGroup("root");
ServiceLoader serviceLoader = ServiceLoader.load(ServiceTask.class);
for (ServiceTask task: serviceLoader) {
rootGroup.addTask(task);
}
// Execute all of the tasks
rootGroup.execute();
}
}
内容总结
以上是互联网集市为您收集整理的java – 用于管理任务组的设计模式全部内容,希望文章能够帮你解决java – 用于管理任务组的设计模式所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。