我们假设有3个操作ops1()
,ops2()
和ops3()
。客户端可以请求执行那些3的任何组合。例如,
ops1()
ops2()
ops1()
成功,则执行ops2()
ops1()
并且如果ops1()
成功,则执行ops2()
,如果两者 ops1()和ops2 ()成功然后执行ops3()这可以用于n ops()虽然对我而言只有5个。
实现这个的简单而优雅的方法是什么?有这种模式吗?
答案 0 :(得分:1)
如何将操作放在列表中,查看要在该列表中执行的操作,如果失败,操作会抛出异常?然后,perform方法可以简单地尝试以所需的顺序执行所有方法,直到完成或发生异常为止。
所以
private List<Callable> ops;
public void perform(int... opNums) {
try {
for (int i : opNums) {
ops.get(i-1).call();
}
}
catch(Exception ex) {
}
}
答案 1 :(得分:0)
我看到的解决方案有点像这样:
public void perform(int... ops) {
for(int i : ops) {
switch(i) {
case 1:
//...
// if(taskFailed) return;
break;
case 2:
//...
// if(taskFailed) return;
break;
case 3:
//...
// if(taskFailed) return;
break;
// so on for all 5
}
}
}
这只是一般性的想法,如果语法完全正确则不进行测试。
“taskFailed”的东西是伪代码。
答案 2 :(得分:0)
这样做的方法是
opsX
方法和实现此方法的类定义公共接口。enum
以了解应该调用此公共接口的哪个类实现。此设计的实现可能是
interface CommonOps {
boolean ops();
}
class Ops1 implements CommonOps {
@Override
public boolean ops() {
//...
}
}
class Ops2 implements CommonOps {
@Override
public boolean ops() {
//...
}
}
//and on...
enum OpsOrder {
OPS1,
OPS2,
OPS3
//... and on
;
}
class Orchestrator {
public boolean executeOps(OpsOrder order) {
switch (order) {
case OPS1:
return new Ops1().ops();
case OPS2:
return new Ops2().ops();
//...
default:
throw new IllegalArgumentException("Not supported.");
}
throw new UnsupportedOperationException("This exception should never be reached.");
}
public boolean orchestrate(OpsOrder ... orders) {
for (OpsOrder order : orders) {
if (!executeOps(orders)) {
return false;
}
}
return true;
}
}
通过拥有CommonOps
类实现的工厂,这可能更加通用,因此Orchestrator
不应该知道将调用哪个CommonOps
:
final class CommonOpsFactory {
private CommonOpsFactory () { }
public static CommonOps create(OpsOrder order) {
switch (order) {
case OPS1:
return new Ops1();
case OPS2:
return new Ops2();
//...
default:
throw new IllegalArgumentException("Not supported.");
}
}
}
class Orchestrator {
public boolean executeOps(OpsOrder order) {
return CommonOpsFactory.create(order).ops();
}
public boolean orchestrate(OpsOrder ... orders) {
for (OpsOrder order : orders) {
if (!executeOps(orders)) {
return false;
}
}
return true;
}
}
答案 3 :(得分:0)
我会将命令模式与Decorator结合使用来解决这个问题。你的命令,如果很多,将包装/装饰彼此:
public class Command{
private Command subCommand;
public Command(Command subCommand){
this.subCommand=subCommand;
}
public Command(){};
public Command addSubCommand(Command command)
{
subCommand=command;
return command;
}
//A Command class is decorating itself
//by adding a behavior over its subcommand
public void execute() throws CommandExecutionException {
executeImpl();
if(subCommand!=null) subCommand.execute();
}
protected void executeImpl() throws CommandExecutionException {
//To be overiden
}
}
public class CommandA extends Command{
private CommandAExecutor ops1Handler;
protected void executeImpl(){
ops1Handler.ops1();
}
}
//....
public class CommandN extends Command{
private CommandNExecutor opsNHandler;
protected void executeImpl(){
opsNHandler.opsN();
}
}
public class Tester{
public static void main(String[] args){
Command commandA = new CommandA(new CommandAExecutor());
Command commandB = new CommandB(new CommandBExecutor());
Command commandN = new CommandN(new CommandNExecutor());
//The order here is A, N, B
commandA.addSubCommand(commandN).addSubCommand(B);
try{
commandA.execute();
}catch(CommandExecutionException e){
//...failure
}
}
}