重复代码命令类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相同的更多属性。