概念
命令模式很容易理解,每当我们点击键盘也是在对计算机发起命令,就是发起号令,然后对象接收到命令进行具体执行。
实现
案例:我们在学生时代都有军训过吧,那肯定是一段难忘的记忆了。教官训练我们的时候,都会发出号令,而这些号令都属于命令,下面就用命令模式实现这个场景:
我们教官发出命令时都会是向前或者向后的,此处简化就不弄向左向右了,有兴趣的朋友可以自己进行补充
首先定义命令这个抽象类:
/**
* 定义一个命令抽象类,里面有三个方法
*/
public abstract class Command {
//教官命令前进
public abstract void forward();
//教官命令后退
public abstract void backward();
//执行
public abstract void execute();
}
然后创建命令发出的对象,也就是本个案例中的教官:
/**
* 创建命令号发者
*/
public class Instructor {
private String name;
public Instructor(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
接下来就是命令的不同实现了,比如说跑步命令,慢跑命令,踏步走命令:
/**
* 跑步命令
*/
public class RunCommand extends Command{
private Instructor instructor;
public RunCommand(Instructor instructor) {
this.instructor = instructor;
}
@Override
public void forward() {
System.out.println(instructor.getName() + "发出命令向前跑!!!向前跑!!!向前跑!!!向前跑!!!");
}
@Override
public void backward() {
System.out.println(instructor.getName() + "发出命令向后跑!!!向后跑!!!向后跑!!!向后跑!!!");
}
@Override
public void execute(){
//定义一个随机数用于判断是执行哪种命令,免得说教官苛刻
Random random = new Random();
int x = random.nextInt(100);
//判断,如果随机数%2等于0,就向前,否则,向后
if(x % 2 == 0){
forward();
}else {
backward();
}
}
}
/**
* 慢跑命令
*/
public class JogCommand extends Command {
private Instructor instructor;
public JogCommand(Instructor instructor) {
this.instructor = instructor;
}
@Override
public void forward() {
System.out.println(instructor.getName() +"发出命令向前慢走!!!向前慢走!!!向前慢走!!!向前慢走!!!");
}
@Override
public void backward() {
System.out.println(instructor.getName() +"发出命令向后慢走!!!向后慢走!!!向后慢走!!!向后慢走!!!");
}
@Override
public void execute(){
//定义一个随机数用于判断是执行哪种命令,免得说教官苛刻
Random random = new Random();
int x = random.nextInt(100);
//判断,如果随机数%2等于0,就向前,否则,向后
if(x % 2 == 0){
forward();
}else {
backward();
}
}
}
/**
* 踏步走命令
*/
public class StepCommand extends Command {
private Instructor instructor;
public StepCommand(Instructor instructor) {
this.instructor = instructor;
}
@Override
public void forward() {
System.out.println(instructor.getName() + "发出命令向前踏步走!!!向前踏步走!!!向前踏步走!!!向前踏步走!!!");
}
@Override
public void backward() {
System.out.println(instructor.getName() + "发出命令向后踏步走!!!向后踏步走!!!向后踏步走!!!向后踏步走!!!");
}
@Override
public void execute(){
//定义一个随机数用于判断是执行哪种命令,免得说教官苛刻
Random random = new Random();
int x = random.nextInt(100);
//判断,如果随机数%2等于0,就向前,否则,向后
if(x % 2 == 0){
forward();
}else {
backward();
}
}
}
再需要创建我们接收命令的对象,也就是学生:
/**
* 创建命令调用类
* 学生就是接收命令的对象
*/
public class Student {
//创建一个list保存一系列命令
private List<Command> list = new ArrayList<>();
//接收命令
public void receive(Command command){
list.add(command);
}
//执行命令
public void execute(){
for(Command command : list){
command.execute();
}
}
}
最后就是我们的实现类了:
public class Training {
//正式训练中
public static void main(String[] args) {
//ctb教官来咯,他带着命令走来咯
Instructor instructor = new Instructor("ctb");
//分别发出三种命令
RunCommand runCommand = new RunCommand(instructor);
JogCommand jogCommand = new JogCommand(instructor);
StepCommand stepCommand = new StepCommand(instructor);
//创建执行对象
Student student = new Student();
//执行对象要接收命令了
student.receive(runCommand);
student.receive(jogCommand);
student.receive(stepCommand);
//执行命令
student.execute();
}
}
实验结果:
优点:封装性非常好,因为这种模式把发出命令的一端和执行命令的一段分开了,扩展性也有很好的保障。
缺点:如果命令比较多,Command的子类可能要实现几十个甚至几百个,容易产生类膨胀。
本文的代码:https://pan.baidu.com/s/1UEB3yQ1mIwq5o4sVjklpCQ
提取码:sl15