重复代码命令类Java

重复代码命令类Java,java,command,code-duplication,Java,Command,Code Duplication,我有两个实现命令的类(使用命令模式),一个是创建工作表: public class CommandCreateSheet implements Command { private Workbook workbook; private String sheetName; public CommandCreateSheet(Workbook workbook, String workSheetName) { this.workbook = workbook

我有两个实现命令的类(使用命令模式),一个是创建工作表:

public class CommandCreateSheet implements Command {

    private Workbook workbook;
    private String sheetName;

    public CommandCreateSheet(Workbook workbook, String workSheetName) {
        this.workbook = workbook;
        this.sheetName = workSheetName;
    }

    @Override
    public void execute() {
        this.workbook.addSheet(this.sheetName);
    }

    @Override
    public void undo() {
        this.workbook.removeSheet(this.sheetName);
    }
}
另一个是删除:

public class CommandDeleteSheet implements Command {

    private Workbook workbook;
    private String sheetName;

    public CommandDeleteSheet(Workbook workbook, String workSheetName) {
        this.workbook = workbook;
        this.sheetName = workSheetName;
    }

    @Override
    public void execute() {
        this.workbook.removeSheet(this.sheetName);
    }

    @Override
    public void undo() {
        this.workbook.addSheet(this.sheetName);
    }
}
如何避免重复代码


谢谢

您可以创建两个命令都实现的中间抽象类

public abstract class AbstactSheetCommand implements Command
{
    private Workbook workbook;
    private String sheetName;

    protected AbstractSheetCommand(Workbook workbook, String workSheetName)
    {
        this.workbook = workbook;
        this.sheetName = workSheetName;
    }

    public abstract void execute();
    public abstract void undo();
}
然后你的子类会小得多:

public class CommandCreateSheet extends AbstractSheetCommand
{
    public CommandCreateSheet(Workbook workbook, String workSheetName)
    {
        super(workbook, workSheetName);
    }

    @Override
    public void execute() { this.workbook.addSheet(this.sheetName); }

    @Override
    public void undo() { this.workbook.removeSheet(this.sheetName);}
}

public class CommandDeleteSheet extends AbstractSheetCommand
{
    public CommandDeleteSheet(Workbook workbook, String workSheetName)
    {
        super(workbook, workSheetName);
    }

    @Override
    public void execute() { this.workbook.removeSheet(this.sheetName); }

    @Override
    public void undo() { this.workbook.addSheet(this.sheetName); }
}
这样做的好处是,您可以轻松添加同一“类别”(可以说)中具有更具体功能的新命令

public class CommandRenameSheet extends AbstractSheetCommand
{
    private String newWorkSheetName;

    public CommandDeleteSheet(Workbook workbook, String oldWorkSheetName, String newWorkSheetName)
    {
        super(workbook, oldWorkSheetName);
        this.newWorkSheetName = newWorkSheetName;
    }

    @Override
    public void execute() 
    { this.workbook.renameSheet(this.sheetName, newWorkSheetName); }

    @Override
    public void undo() 
    { this.workbook.renameSheet(newWorkSheet, this.sheetName); }
}

对于像您这样的短代码,您通过尝试删除代码节省的很少,而且您保存的代码越多,您的解决方案就越复杂

但是这里有一个使用抽象类的Java8实现

public abstract class SheetCommand implements Command {

    private Runnable executeAction, undoAction;

    public SheetCommand(Runnable executeAction, Runnable undoAction) {
        this.executeAction = executeAction;
        this.undoAction = undoAction;
    }

    @Override
    public void execute() {
        executeAction.run();
    }

    @Override
    public void undo() {
        undoAction.run();
    }
}

public class CommandCreateSheet extends SheetCommand {

    public CommandCreateSheet(Workbook workbook, String workSheetName) {
        super(() -> workbook.addSheet(workSheetName),
              () -> workbook.removeSheet(workSheetName));
    }
}

public class CommandDeleteSheet extends SheetCommand {

    public CommandDeleteSheet(Workbook workbook, String workSheetName) {
        super(() -> workbook.removeSheet(workSheetName),
              () -> workbook.addSheet(workSheetName));
    }
}
此实现使用lambda表达式来表示需要执行的操作。因为lambda表达式是闭包,所以不需要显式保留实际工作簿和工作表名称引用-它们隐藏在lambda表达式中


对于
execute
undo
中更复杂的代码,您可以像最初那样自己编写方法,这样做可能会做得更好-如果您尝试使用lambdas,您将得到比原来更复杂、更不可读的代码。

我觉得这段代码不错。您可以通过创建一个带有字段
工作簿
图纸名
的抽象超类。可能只有当你需要很多子类的时候才值得,但对于这么小的代码来说几乎不值得。您仍然需要方法
execute
undo
或多或少保持不变,因为它们是特定于类的,并且您仍然需要声明构造函数(因为构造函数不是继承的),所以这对您没有多大好处。我创建了AbstractCommand,它改进了解决方案,但我还是收到了重复的代码:splus1。由于
SheetCommand
没有任何抽象方法(据我们所知),因此最好将其设置为非抽象的,并使用静态工厂而不是子类。@PaulBoddington对发生的事情感到抱歉,我们似乎在并行工作。我在考虑一个非抽象类,但我不确定每次我们使用新命令时是否需要更改head类(添加一个静态方法)。我想这要视情况而定。发生的一切都是我的错。我发布了一个荒谬的答案,其中包含对相同对象的重复引用。我同意,我们没有足够的信息来提供完美的解决方案。我认为@Nik G发布的解决方案可以。这对我的知识来说比较容易。谢谢很好,我也有一个CommandSetCell类,具有与您建议的CommandRenameSheet相同的更多属性。