1.支持的操作符有"+", "-", "*", "/"
2.撤销符号为"<"
3.例如输入"1", "+", "2", "<", "+", "1", "<", "+", "3",输出计算结果4
4.例如输入"100", "/", "2", "<", "+", "5", "<", "*", "4", “+", "1", "-", "10", "<", "<",输出计算结果400
要求:1)使用TDD
2)使用命令模式
5.简单类图设计
6.单元测试
package com.pattern.command;
import junit.framework.Assert;
import org.junit.Test;
import com.pattern.command.undocalc.UndoCalc;
public class UndoCalcTest {
@Test
public void testInit() {
UndoCalc calc = new UndoCalc();
String ret = calc.calc("1");
Assert.assertEquals("1", ret);
}
@Test
public void testAddCmd1() {
UndoCalc calc = new UndoCalc();
String ret = calc.calc("1", "+", "2", "<", "+", "1", "<", "+", "3");
Assert.assertEquals("4", ret);
}
@Test
public void testAddCmd2() {
UndoCalc calc = new UndoCalc();
String ret = calc.calc("1", "+", "2", "+", "1", "<", "+", "3");
Assert.assertEquals("6", ret);
}
@Test
public void testAddCmd3() {
UndoCalc calc = new UndoCalc();
String ret = calc.calc("1", "+", "2", "+", "1", "+", "3");
Assert.assertEquals("7", ret);
}
@Test
public void testAddCmd4() {
UndoCalc calc = new UndoCalc();
String ret = calc.calc("1", "+", "2", "+", "1", "+", "3", "<", "<");
Assert.assertEquals("3", ret);
}
@Test
public void testSubCmd1() {
UndoCalc calc = new UndoCalc();
String ret = calc.calc("1", "-", "2", "<", "-", "1", "<", "-", "3");
Assert.assertEquals("-2", ret);
}
@Test
public void testSubCmd2() {
UndoCalc calc = new UndoCalc();
String ret = calc.calc("1", "-", "2", "-", "1", "<", "-", "3");
Assert.assertEquals("-4", ret);
}
@Test
public void testAddSubCmd() {
UndoCalc calc = new UndoCalc();
String ret = calc.calc("1", "+", "2", "-", "1", "<", "-", "3");
Assert.assertEquals("0", ret);
}
@Test
public void testMulCmd() {
UndoCalc calc = new UndoCalc();
String ret = calc.calc("2", "*", "2", "<", "*", "3", "<", "*", "6");
Assert.assertEquals("12", ret);
}
@Test
public void testDevCmd() {
UndoCalc calc = new UndoCalc();
String ret = calc.calc("100", "/", "2", "<", "/", "5", "<", "/", "4");
Assert.assertEquals("25", ret);
}
@Test
public void testAllCmd() {
UndoCalc calc = new UndoCalc();
String ret = calc.calc("100", "/", "2", "<", "+", "5", "<", "*", "4",
"+", "1", "-", "10", "<", "<");
Assert.assertEquals("400", ret);
}
@Test
public void testExceptionCmd() {
UndoCalc calc = new UndoCalc();
String ret = calc.calc("100", "<", "<");
Assert.assertEquals("ERROR INPUT", ret);
}
}
7.源码
package com.pattern.command.undocalc;
import java.util.Arrays;
import java.util.List;
import net.mindview.util.Stack;
public class UndoCalc {
int result;
public String calc(String... cmd) {
try {
result = Integer.valueOf(cmd[0]);
for (int i = 1; i < cmd.length; ++i) {
String c = cmd[i];
if (isOperator(c)) {
Operator op = getNewOperator(c);
String nextC = cmd[++i];
result = op.calc(result, Integer.valueOf(nextC));
pushOp((Undoable) op);
} else if (isUndo(c)) {
Undoable op = popOp();
result = op.undo();
}
}
return String.valueOf(result);
} catch (Exception e) {
return "ERROR INPUT";
}
}
private Stack<Undoable> opStack = new Stack<Undoable>();
private Undoable popOp() {
return opStack.pop();
}
private void pushOp(Undoable op) {
opStack.push(op);
}
private boolean isUndo(String c) {
return "<".equals(c);
}
private Operator getNewOperator(String c) {
if ("+".equals(c)) {
return new UndoAddOperator();
} else if ("-".equals(c)) {
return new UndoSubOperator();
} else if ("*".equals(c)) {
return new UndoMulOperator();
} else if ("/".equals(c)) {
return new UndoDevOperator();
}
return null;
}
private static String[] ops = new String[] { "+", "-", "*", "/" };
private static List<String> opList = Arrays.asList(ops);
private boolean isOperator(String c) {
return opList.contains(c);
}
}
package com.pattern.command.undocalc;
public interface Undoable {
int undo();
}
package com.pattern.command.undocalc;
public interface Operator {
int calc(int result, Integer second);
}
package com.pattern.command.undocalc;
public abstract class UndoableOperator implements Undoable {
int backUp;
protected void backUpForUndo(int result) {
backUp = result;
}
@Override
public int undo() {
return backUp;
}
}
package com.pattern.command.undocalc;
public class AddOperator implements Operator {
@Override
public int calc(int result, Integer second) {
return result + second;
}
}
package com.pattern.command.undocalc;
public class DevOperator implements Operator {
@Override
public int calc(int result, Integer second) {
return result / second;
}
}
package com.pattern.command.undocalc;
public class MulOperator implements Operator {
@Override
public int calc(int result, Integer second) {
return result * second;
}
}
package com.pattern.command.undocalc;
public class SubOperator implements Operator {
@Override
public int calc(int result, Integer second) {
return result - second;
}
}
package com.pattern.command.undocalc;
public class UndoAddOperator extends UndoableOperator implements Operator {
Operator op = new AddOperator();
@Override
public int calc(int result, Integer valueOf) {
backUpForUndo(result);
return op.calc(result, valueOf);
}
}
package com.pattern.command.undocalc;
public class UndoDevOperator extends UndoableOperator implements Operator {
Operator op = new DevOperator();
@Override
public int calc(int result, Integer valueOf) {
backUpForUndo(result);
return op.calc(result, valueOf);
}
}
package com.pattern.command.undocalc;
public class UndoMulOperator extends UndoableOperator implements Operator {
Operator op = new MulOperator();
@Override
public int calc(int result, Integer valueOf) {
backUpForUndo(result);
return op.calc(result, valueOf);
}
}
package com.pattern.command.undocalc;
public class UndoSubOperator extends UndoableOperator implements Operator {
Operator op = new SubOperator();
@Override
public int calc(int result, Integer valueOf) {
backUpForUndo(result);
return op.calc(result, valueOf);
}
}
package com.pattern.command.undocalc;
public interface OperatorFactory {
Operator getOperator(String operator);
}
package com.pattern.command.undocalc;
public class NoramlOperatorFactory implements OperatorFactory {
@Override
public Operator getOperator(String operator) {
if ("+".equals(operator)) {
return new AddOperator();
} else if ("-".equals(operator)) {
return new SubOperator();
} else if ("*".equals(operator)) {
return new MulOperator();
} else if ("/".equals(operator)) {
return new DevOperator();
}
return null;
}
}
package com.pattern.command.undocalc;
public class UndoOperatorFactory implements OperatorFactory{
@Override
public Operator getOperator(String operator) {
if ("+".equals(operator)) {
return new UndoAddOperator();
} else if ("-".equals(operator)) {
return new UndoSubOperator();
} else if ("*".equals(operator)) {
return new UndoMulOperator();
} else if ("/".equals(operator)) {
return new UndoDevOperator();
}
return null;
}
}