`
nathan09
  • 浏览: 145671 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

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

}


分享到:
评论

相关推荐

    命令模式实现简单计算器功能包括撤销

    考虑一个计算器功能,只能实现加法和减法运算。但是,这个计算器支持撤销操作。

    有撤销功能的计算器(java)

    有撤销功能的计算器(纯java) 有撤销功能的计算器(纯java)

    行为模式 Java实现 IDEA工程

    考虑一个计算器功能,只能实现加法和减法...1、明确可使用什么设计模式来实现这个计算器 2、画出适合上述设计模式的类图 3、给出相关代码。其中add方法是加法运算,sub是减法运算 4、以分组为单位认真完成实验报告。

    吴天雄--vim编辑器.doc

    本文档主要总结vim编辑器重点知识内容,第一部分:vi介绍,第二部分:vim三种模式(命令模式、末行模式、编辑模式),第三部分:命令模式(光标移动,复制操作,剪切/删除操作,撤销/恢复操作,光标的快速移动),第...

    arcgis工具

    执行命令: &lt;空间分析&gt;-&lt;栅格计算器&gt; 构造表达式:[Landuse]*[polyClip4-polyclip4] ,执行栅格图层:Landuse 和 用以剪切 的栅格polyClip4 之间的相乘运算 GIS软件应用-ArcGIS 得到的结果即是以任意多边形剪切的...

    lexyaccmingw

    * 观察者模式普通实现 * 观察者模式中的必备元素 * 将观察者模式普通实现自动化 * 将观察者模式标准化 * 一个使用自动化观察者模式的复杂例子 * 撤销和重做(Undo/Redo)的C++自动化实现 ...

    Altium Designer Beta 19.0.10完整版安装包+安装教程+和谐文件

    更新了图层堆栈管理器,其中包含用于堆栈定义,uVia支持,材料库,阻抗计算器等的新文档界面和UI增强功能。 26862 解决了CAMtastic问题,其中设计规则值被错误地舍入到一个小数位。 26953 修复了在PCB库编辑器(BC:...

    Excel VBA实用技巧大全 附书源码

    03017判断工作表是否处于筛选模式 03018判断工作表是否存在(之一) 03019判断工作表是否存在(之二) 03020判断工作表是否自动重新计算 03021判断工作表被保护时是否可以进行自动筛选的操作 03022判断工作表被保护...

    计算机应用技术(实用手册)

    请确认您的显示卡可以支持您所选择的模式,一般用默认的就可以。 4.Integrated Peripherals(集成设备设定) 这个是管理计算机的主板集成设备和端口的选项,具体项目因为主板不同,所以其中的设置会有所不同。 ...

Global site tag (gtag.js) - Google Analytics