`
nathan09
  • 浏览: 150894 次
  • 性别: 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;
	}

}


分享到:
评论

相关推荐

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

    在这个简单的计算器例子中,我们将探讨如何使用命令模式来实现加法、减法运算以及撤销功能。 首先,我们有以下几个主要角色: 1. **命令接口(Command)**:定义了执行特定计算操作的抽象方法,如`execute()`。例如...

    设计模式之命令模式Java实现

    命令模式是一种行为设计模式,它将请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。在Java中实现命令模式,我们可以按照以下步骤进行: 1. **定义...

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

    这个简单的有撤销功能的Java计算器展示了如何利用面向对象编程、数据结构(如栈)以及错误处理来实现一个实用的工具。通过扩展这个基础设计,可以创建更复杂的计算器,支持更多功能,如括号、优先级、变量等。这个...

    C#版 简易 计算器

    8. **设计模式**:虽然这是一个简单的应用,但可能也会运用到一些设计模式,如命令模式(Command Pattern),用于封装操作并支持撤销/重做功能。 9. **代码组织**:良好的代码组织可以使程序更易于理解和维护。可能...

    cadence计算器使用教程

    这部分与常规计算器相似,但具有额外的功能,例如`undo`键,可以在算术模式和逆波兰模式中撤销操作。其他按键包括: - 数字键:0-9 - 运算符:+ - * / - `undo`键:撤销上一步操作 ##### 3. 函数键 - **三角函数*...

    设计模式之Command(命令)模式

    2. **不适用于简单操作**:如果一个操作过于简单,使用命令模式可能会显得过度设计。 **案例分析** 在提供的资源中,"计算器"可能是使用Command模式的一个实例。每个运算(加法、减法等)可以看作一个具体的命令,...

    .NET计算器

    9. **设计模式**:开发过程中可能会使用到设计模式,如命令模式(Command Pattern),将每项运算封装成一个命令对象,使得操作可以被撤销或重做。 10. **单元测试**:为了确保计算器的正确性,开发者可能会编写单元...

    基于java实现的GUI图形化界面的简单计算器,实现加减乘除、乘方,可以连续运算,带一定纠错功能

    8. **设计模式**:尽管没有直接提及,但这个项目可能使用了设计模式,如命令模式(Command Pattern)来封装操作和参数,使得计算过程可以被撤销或重做;或者模型-视图-控制器(MVC)架构,将界面、业务逻辑和数据...

    JAVA编写计算器(支持带括号)

    - **命令模式**:可以将每一步计算作为一个命令,这样方便实现撤销/重做功能。 - **状态模式**:如果计算器有多种工作模式(如科学计算、普通计算等),可以通过状态模式来切换和管理不同模式的行为。 6. **用户...

    c#windows科学计算器

    7. **设计模式**:考虑使用命令模式来封装每个计算操作,这样可以方便地撤销和重做操作。同时,也可以利用状态模式来管理计算器的不同计算阶段,如等待输入、进行运算等。 在“李钦运计算器”这个项目中,开发者...

    Java_用JAVA实现一个计算器_

    6. **设计模式**:在实现计算器的过程中,可能会用到一些设计模式,比如命令模式(Command Pattern),可以将每一步操作封装成一个命令对象,方便撤销/重做功能的实现。 7. **布局管理**:为了使计算器界面美观且...

    C# 简易计算器

    3. **命令模式**:将请求封装为一个对象,使得可以在不同的时间参数化不同的请求,以及支持可撤销的操作。计算器的按钮点击事件可以转化为命令对象,执行相应的计算操作。 在这个项目中,你将学习如何将这些面向...

    科学计算器(C++版)

    - 科学计算器可能采用命令设计模式,其中每个操作(加、减、乘、除)都是一个命令对象,可以被存储、撤销或重做,提供更高级的用户交互。 7. **编译与调试**: - 使用C++编译器如GCC或Clang将源代码编译成可执行...

    JiSuanQi_计算器QT_Qt简单计算器_ablem2u_

    同时,考虑到用户体验,可能会有撤销和重做功能,这通常通过MVC模式中的命令设计模式来实现。 综上所述,这个“JiSuanQi”项目展示了Qt的GUI编程基础,包括UI设计、信号和槽机制、事件处理、数学运算以及资源管理等...

    MFC 计算器

    虽然没有明确提及,但MFC的事件驱动模型和命令模式在这里发挥了作用。每个按钮点击被视为一个命令,由消息映射机制转发给相应的处理函数执行。 总结,MFC 计算器项目是一个学习MFC基础和Windows GUI编程的好实例。...

    一个Java编写的计算器的程序

    5. **设计模式**:计算器程序可能应用到设计模式,比如命令模式,可以将每项操作封装成一个命令对象,便于管理和撤销/重做操作。 6. **类与对象设计**:可能有一个Calculator类作为主要的业务逻辑容器,它可能包含...

    设计模式 的简单示例

    命令模式将请求封装为一个对象,使得我们可以使用不同的请求、队列请求或者支持撤销操作。在计算器中,每个运算(如加法、减法、乘法和除法)都可以视为一个命令。 1. 命令接口: 定义一个通用的接口`...

    java实验 计算器

    尽管这是一个简单的项目,也可以引入设计模式,比如命令模式,将每次操作封装成一个命令对象,这样可以方便地实现撤销/重做功能。 8. **文档与注释**: 实验中的文档通常包括程序的描述、使用方法和代码注释。...

    计算器java小程序

    - `jp3` 使用 `GridLayout` 布局管理器,实现计算器的标准布局。 2. **菜单栏**: - 创建了包含“颜色”和“帮助”的菜单栏。 - “颜色”菜单下提供了三种颜色选项:“红色”、“蓝色”、“黄色”。 3. **按钮...

    1602液晶显示的计算器,基于80C51

    在这个项目中,我们将探讨如何利用80C51来实现一个简单的计算器,并结合1602液晶显示器进行结果显示。 1602液晶显示器是一种常见的字符型LCD(液晶显示屏),常用于嵌入式系统中的数据显示。它通常有16个字符、2行...

Global site tag (gtag.js) - Google Analytics