如何使用变量(数量)参数从动态上下文创建和配置Command对象?

时间:2015-07-09 09:33:40

标签: java oop design-patterns configuration command-pattern

SO!我在代码设计方面陷入了僵局。这是场景。

我需要复制,移动或删除文件。好的,当然,没问题。我可以像这样轻松地写出来。

public class SimpleFileManager {
    public void copy(String sourcePath, String targetPath) { ... }
    public void move(String sourcePath, String targetPath) { ... }
    public void delete(String filePath) { ... }
}

并以类似的方式从客户端代码中调用它,例如:

public static void main(String[] args) {
    ...
    fileManager.copy(x, y);
    ...
}

但是,出现了一些请求,即某些具有FileManager引用的特定POJO执行特定操作,具体取决于某些配置。 POJO实例的实际规范应该包含在config。

这是我的意思的一个例子:

public static void main(String[] args) {
    ...
    InvokerPojo invokerPojo1 = new InvokerPojo(invokerPojo1Config, fileManager); // this config tells it to copy files only
    InvokerPojo invokerPojo2 = new InvokerPojo(invokerPojo2Config, fileManager); // this config tells it to move files only
    InvokerPojo invokerPojo3 = new InvokerPojo(invokerPojo3Config, fileManager); // this config tells it to delete files only
}

因此,FileManager提供了执行实际操作的功能,而InvokerPojo只是根据配置调用和委托这些方法。

但是,我不想加入FileManager,因为,例如,我可能会找到一些提供相同功能但比我的好得多的库。

所以,我在想这样的事情:

public interface FileManagerDelegator {
    void copy(String sourcePath, String targetPath);
    void move(String sourcePath, String targetPath);
    void delete(String filePath);
}

public class MyFileManagerDelegator implements FileManagerDelegator {
    private SimpleFileManager simpleFileManager;

    void copy(String sourcePath, String targetPath) { // delegate to simpleFileManager }
    void move(String sourcePath, String targetPath) { // delegate to simpleFileManager }
    void delete(String filePath) { // delegate to simpleFileManager }
}

public class ComplexFileManagerDelegator implements FileManagerDelegator {
    private ComplexFileManager complexFileManager;

    void copy(String sourcePath, String targetPath) { // delegate to complexFileManager }
    void move(String sourcePath, String targetPath) { // delegate to complexFileManager }
    void delete(String filePath) { // delegate to complexFileManager }
}

public interface Command {
    void execute();
}

public class CopyCommand() {
    private FileManagerDelegator delegator;
    String sourcePath;
    String targetPath;

    void execute() {
        delegator.copy(sourcePath, targetPath);
    }
}

public class MoveCommand() {
    private FileManagerDelegator delegator;
    String sourcePath;
    String targetPath;

    void execute() {
        delegator.move(sourcePath, targetPath);
    }
}

public class DeleteCommand() {
    private FileManagerDelegator delegator;
    String filePath;

    void execute() {
        delegator.delete(filePath);
    }
}

public static void main(String[] args) {
    ...
    Command c = getCommand(context);
    c.execute();
    ...
}

现在,问题在于实际创建该特定命令,因为我不想知道正在创建哪个命令。我所知道的是在上下文中存在创建它的信息。

我正在考虑建立一个可以从上下文创建适当命令的工厂。

主要问题在于命令的参数数量。 如果存在的唯一操作是复制和移动,那么它将很容易

public interface Command {
    void execute(String a, String b);
}

但是,由于删除操作只需要一个,所以我要么必须忽略调用中的另一个参数,要么添加另一个接口方法,我认为两者都不好。<登记/> 我也不想发送像这样的可变数量的参数:

public interface Command {
    void execute(String ... args);
}

因为它之前的设计糟糕的设计只是一个更漂亮的版本。

那么,基于上下文的工厂是否会更加清洁,我的客户端代码不知道正在调用哪个操作,以及哪个接收器:

2个上下文的示例:

Context copyContext = new Context();
copyContext.set("OPERATION", "COPY");
copyContext.set("sourcePath", sourcePath);
copyContext.set("targetPath", targetPath);

Context deleteContext = new Context();
deleteContext.set("OPERATION", "DELETE");
deleteContext.set("filePath", filePath);

然后,在工厂里,我可以这样做:

Command getCommand(FileManagerDelegator delegator, Context context) {
    String operation = context.get("OPERATION");

    if (operation.equals("COPY")) {
        String sourcePath = context.get("sourcePath");
        String targetPath = context.get("targetPath");
        return new CopyCommand(sourcePath, targetPath, delegator);
    } else if (operation.equals("DELETE")) {
        String filePath = context.get("filePath");
        return new DeleteCommand(filePath, delegator);
    } else {
        ...
    }
}

是否有更清晰,更可配置的方法来动态创建参数化命令对象(从上下文动态配置它们),这些命令对象使用不同(多个)参数进行操作?

0 个答案:

没有答案