使用命令模式实现简单的支持撤销的计算器

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 opStack = new Stack();

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

}


你可能感兴趣的:(使用命令模式实现简单的支持撤销的计算器)