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; } }