欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

设计模式应用教程4:可撤销的命令-悔棋

程序员文章站 2022-03-10 17:29:08
...

字符界面的运行截图:

设计模式应用教程4:可撤销的命令-悔棋

工程结构:

设计模式应用教程4:可撤销的命令-悔棋

悔棋的关键,是具体命令怎样保存、撤销下棋的参数。

有两种方案:1. 用一个字符串"x,4,y,3,type,1"存放所有数据,也可以是JSON。

2. 用JavaBean封装。

package com_20181616666_YanYang;

import java.util.ArrayList;
//方案2:棋子坐标、棋子类型整合成一个类
//  命令参数类 CommandParamBean(JavaBean) 
/*
 *  class CommandParamBean
 *  { int x; int y; int type;
 *  }
 *  
 *  ArrayList<CommandParamBean> c_param_list
 */
public class ConcreteCommand implements Command{

	//用ArrayList保存命令参数:棋子坐标、棋子类型 4.3
	//方案1:棋子坐标、棋子类型整合成字符串
	//  "x,4,y,3,type,1" 
	//  "x,8,y,4,type,2" 
	// 二维数组的游戏地图:执黑1,执白2 ,0没有
	public ArrayList<String> c_param_list
				=new ArrayList<String>();
	
	public Chess chess;
	//传入三连,传入接收者
	public ConcreteCommand(Chess chess) {
		this.chess = chess;
	}
	public void execute(int x,int y,int type)
	{
		//1.写到游戏地图的二维数组中,画出棋盘
		chess.puddown(x, y, type);
		//2. 把命令参数,保存到课本4.3 命令参数数组
		// 逗号分隔,拼接成了字符串
		c_param_list.add("x,"+x+",y,"+y+",type,"+type);
	}
	
	//不带参数,由具体命令根据命令参数数组:ArrayList<String>
//	找到上一步的数据,撤销上一步数据
	public void undo()
	{
		//方案1:字符串的解析。取出最后一个元素"x,8,y,4,type,2" 
		int i=c_param_list.size()-1;
		String s=c_param_list.get(i);
		String sub[]=s.split(",");
		int x= Integer.parseInt( sub[1]);
		int y= Integer.parseInt( sub[3]);;
		int type= Integer.parseInt( sub[5]);;
		chess.undo(x, y, type);
		
		//命令参数数组,删除末尾元素
		c_param_list.remove(i);
		//方案2:CommandParamBean bean;
		// bean.x  bean.y  bean.type
	}
}

接收者很简单,现在是字符输出,如果加入二维数组,就能接入图形界面:

//接收者
public class Chess {

	//2018级  20行10列的俄罗斯方块
	public int [][] gamemap=new int[19][19];
	public String []  text={"空","黑子","白子"};
	
	//单机版、联机版
	// param: name,date,room 1v1
	public void puddown(int x,int y,int type)
	{
		System.out.println("落子"+x+","+y+","+text[type]);
	}
	public void undo(int x,int y,int type)
	{
		System.out.println("悔棋"+x+","+y+","+text[type]);
	}	
}

请求者的代码,也很简单:

public class Player {

	Command command;
	
	public void setCommand(Command command) {
		this.command = command;
	}
	
	public void execute(int x,int y,int type)
	{
		command.execute(x, y, type);
	}
	
	public void undo()
	{
		command.undo();
	}
}

即使是一个大型项目,关键部分的代码也不多。不是靠简单代码的堆积,形成大型项目。很多功能,界面无关。比如做一个字符界面的聊天室,也需要很好、很全面的基本功。

用了命令模式的好处,请求者的撤销函数undo, 不需要带参数。