在王者荣耀角度下分析面向对象程序设计B中23种设计模式之命令模式

2021-02-02 17:15:09 浏览数 (1)

命令模式在王者荣耀中的应用

命令模式应用一:

命令模式应用二(“多按钮”应用):

一、简述

王者荣耀是一款5v5的团队竞技游戏,良好的团队信息交流可以让玩家更好地领略英雄竞技的酣畅淋漓!为了保证局内交流的有效性和快捷性,天美团队在制作游戏时,在小地图下边设置了三个“开始撤退”、“发起进攻”、“请求集合”按钮(如上图箭头所指)。

二、命令模式

命令模式理解: 把操作写在类里面,作为函数调用它; 调用者实现功能时只需调用Command抽象类的execute()方法就可以,不需要了解到底是哪个接收者执行。 命令模式是一种高内聚的模式。

命令模式的结构中包括四种角色接收者(Receiver):执行具体行为、请求。 命令(Command)接口:命令的统一父类抽象类/接口 具体命令(ConcreteCommand):具体请求的封装 请求者(Invoker):发出请求

命令模式的UML类图

命令模式的本质封装请求

命令模式的优缺点: 优点:高内聚低耦合、可扩展性、更动态的控制、能很自然地复合命令; 缺点:可能会导致某些系统有过多的具体命令类。

三、王者荣耀角度下实现命令模式代码及结构图

应用一代码实现:

实现此应用的UML类图

eclipse结构图

主函数【应用(Application)】

代码语言:javascript复制
package angle_command;
/*
       main:
       分别创建各个角色,请求者发出请求,间接触发具体行为 
 */
public class Application{
	public static void main(String[]args){
	    //分别创建各个角色
		TeammateRequest1 faqijingong=new TeammateRequest1();  //创建接收者TeammateRequest1
		Command request1_attack=new ConcreteCommandAttack(faqijingong);  //创建具体命令发起进攻并指定接收者TeammateRequest1
		PlayerRequests wanjia=new PlayerRequests();   //创建请求者PlayerRequests 
		//命令模式的使用
		wanjia.setCommand(request1_attack);
		wanjia.startExecute();
		
		TeammateRequest2 qingqiujihe=new TeammateRequest2(); //创建接收者TeammateRequest2
		Command request2_gather=new ConcreteCommandGather(qingqiujihe);//创建具体命令请求集合并指定接收者TeammateRequest2
		wanjia.setCommand(request2_gather);
		wanjia.startExecute();
		
		TeammateRequest3 kaishichetui=new TeammateRequest3();//创建接收者TeammateRequest3
		Command request3_retreat=new ConcreteCommandRetreat(kaishichetui);//创建具体命令开始撤退并指定接收者TeammateRequest3
		wanjia.setCommand(request3_retreat);
		wanjia.startExecute();
	}
}

命令(command)接口

代码语言:javascript复制
package angle_command;
/*
          角色1 : 命令的统一父类(抽象类或接口),声明命令函数,执行命令。
          命令接口中规定了用来封装“请求”的方法
*/
public interface Command {
	public abstract void execute();

}

具体命令(ConcreteCommand)之发起进攻

代码语言:javascript复制
package angle_command;
/*
      角色2.1:具体命令,是命令的子类或实现类
      包含一个接收者的属性成员变量 
      通过命令execute()函数,触发接受者的具体行为
      实现某个请求、操作的封装
*/
public class ConcreteCommandAttack implements Command{
	TeammateRequest1 requests1;//UML 关联关系
	//构造函数传入成员变量
	ConcreteCommandAttack(TeammateRequest1 requests1)
	{
		this.requests1=requests1;
	}
	public void execute(){//玩家的请求:“ConcreteCommandAttack的实例调用attack()”封装到一个具体命令对象的execute()方法中
		requests1.attack();
	}

}

具体命令(ConcreteCommand)之开始撤退`

代码语言:javascript复制
package angle_command;
/*
      角色2.2:具体命令,是命令的子类或实现类
      包含一个接收者的属性成员变量 
      通过命令execute()函数,触发接受者的具体行为
      实现某个请求、操作的封装
*/
public class ConcreteCommandRetreat implements Command{
	TeammateRequest3 requests3;//UML 关联关系
	//构造函数传入成员变量
	ConcreteCommandRetreat(TeammateRequest3 requests3)
	{
		this.requests3=requests3;
	}
	public void execute(){//玩家的请求:“ConcreteCommandRetreat的实例调用retreat()”封装到一个具体命令对象的execute()方法中
		requests3.retreat();
	}

}

具体命令(ConcreteCommand)之请求集合

代码语言:javascript复制
package angle_command;
/*
      角色2.3:具体命令,是命令的子类或实现类
      包含一个接收者的属性成员变量 
      通过命令execute()函数,触发接受者的具体行为
      实现某个请求、操作的封装
*/
public class ConcreteCommandGather implements Command{
	TeammateRequest2 requests2;//UML 关联关系
	//构造函数传入成员变量
	ConcreteCommandGather(TeammateRequest2 requests2)
	{
		this.requests2=requests2;
	}
	public void execute(){//玩家的请求:“ConcreteCommandGather的实例调用gather()”封装到一个具体命令对象的execute()方法中
		requests2.gather();
	}

}

请求者(Invoker)

代码语言:javascript复制
package angle_command;
/*
       角色3:请求者
               包含一个commend,作为属性成员变量 
               通过命令startExecute()函数,发出命令请求
               给请求者传入一个具体命令,再通过命令接口,间接触发了请求操作
*/
public class PlayerRequests {
	Command command;//请求者含有Command的接口声明的变量command,用来存放具体命令的引用
	public void setCommand(Command command)
	{  //command回调具体命令实现的Command的接口的方法(请求者实现具体的命令,实现自己的请求)
		this.command=command;
	}
	public void startExecute(){
		command.execute();
	}

}

接收者(Receiver)

代码语言:javascript复制
package angle_command;
/*
           角色4.1 : 接收者,执行具体的命令、行为
           该实例的attack()方法实现提醒队友“发起进攻”
*/
public class TeammateRequest1 {
	public void attack(){
		System.out.println("发起进攻");
	}

}
代码语言:javascript复制
package angle_command;
/*
           角色4.2 : 接收者,执行具体的命令、行为
           该实例的gather()方法实现提醒队友“请求集合”
*/
public class TeammateRequest2 {
	public void gather(){
		System.out.println("请求集合");
	}

}
代码语言:javascript复制
package angle_command;
/*
           角色4.3 : 接收者,执行具体的命令、行为
           该实例的retreat()方法实现提醒队友“开始撤退”
*/
public class TeammateRequest3 {
	public void retreat(){
		System.out.println("开始撤退");
	}

}

运行结果截图

应用二(“多按钮”应用)代码实现:

实现此应用的eclipse结构图

主函数 Application.java

代码语言:javascript复制
package skillCommand;
/*
         应用类
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Application extends JFrame{
	Invoke requestOneSkill,requestTwoSkill,requestThreeSkill;
	Hero hero;
	
	Application(){
		setTitle("英雄技能释放特效");
		requestOneSkill=new Invoke();
		requestTwoSkill=new Invoke();
		requestThreeSkill=new Invoke();
		hero=new Hero();
		requestOneSkill.setCommand(new OneSkillHeroCommand(hero));
		requestTwoSkill.setCommand(new TwoSkillHeroCommand(hero));
		requestThreeSkill.setCommand(new ThreeSkillHeroCommand(hero));
		initPosition();
		setSize(1000,700);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
	}
	
	private void initPosition(){
		JPanel pSourth=new JPanel();
		pSourth.add(requestOneSkill.getButton());
		pSourth.add(requestTwoSkill.getButton());
		pSourth.add(requestThreeSkill.getButton());
		add(pSourth,BorderLayout.SOUTH);
		JPanel pNorth=new JPanel();
		pNorth.add(hero);
		add(pNorth,BorderLayout.NORTH);
		JPanel pCenter=new JPanel();
		pCenter.setBackground(Color.black);
		pCenter.add(hero);
		add(pCenter,BorderLayout.CENTER);
		setSize(1000,700);
	}

	public static void main(String[] args) {
		Application machine=new Application();

	}

}

接收者 Hero.java

代码语言:javascript复制
package skillCommand;
/*
        角色1:接收者
 */
import javax.swing.*;

public class Hero extends JPanel{
	String name;
	Icon imageIcon;
	JLabel label;
	public Hero(){
		label=new JLabel("英雄释放技能效果");
		add(label);
	} 
	public void one(){
		label.setIcon(new ImageIcon("yijineng.jpg"));  //一技能效果图
	}
	public void two(){
		label.setIcon(new ImageIcon("erjineng.jpg"));  //二技能效果图
	}
	public void three(){
		label.setIcon(new ImageIcon("sanjineng.jpg"));  //三技能效果图
	}

}

命令接口 Command.java

代码语言:javascript复制
package skillCommand;
/*
        角色2:命令接口
 */
public interface Command {
	public abstract void execute();
	public abstract String getName(); 

}

具体命令 OneSkillHeroCommand.java

代码语言:javascript复制
package skillCommand;
/*
        角色3.1:具体命令
*/
public class OneSkillHeroCommand implements Command{
	Hero hero;
	OneSkillHeroCommand(Hero hero){
		this.hero=hero;
	}
	public void execute(){
		hero.one();
	}
	public String getName(){
		return "一技能";
	}

}

TwoSkillHeroCommand.java

代码语言:javascript复制
package skillCommand;

import javax.swing.ImageIcon;

/*
           角色3.2:具体命令
*/
public class TwoSkillHeroCommand implements Command{
	Hero hero;
	TwoSkillHeroCommand(Hero hero){
		this.hero=hero;
	}
	public void execute(){
		hero.two();
	}
	public String getName(){
		return "二技能";
	}

}

ThreeSkillHeroCommand.java

代码语言:javascript复制
package skillCommand;
/*
         角色3.3:具体命令
*/
public class ThreeSkillHeroCommand implements Command{
	Hero hero;
	ThreeSkillHeroCommand(Hero hero){
		this.hero=hero;
	}
	public void execute(){
		hero.three();
	}
	public String getName(){
		return "三技能";
	}

}

请求者 Invoke.java

代码语言:javascript复制
package skillCommand;
/*
      角色4:请求者
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Invoke {
	JButton button;                      //我们需要的按钮
	Command command;
	Invoke(){
		button=new JButton();
		button.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				executeCommand();
			}
		});
	}
	public void setCommand(Command command){
		this.command=command;
		button.setText(command.getName());    //按钮显示命令的名称
	}
	public JButton getButton(){
		return button;
	}
	public void executeCommand(){
		command.execute();
	}

}

运行结果截图:

更多设计模式在王者荣耀中的应用请点击我的→设计模式在王者荣耀中的应用

感谢阅读

END

0 人点赞