java23种设计模式(1)-命令模式

java23种设计模式(1)-命令模式

  基本所有的程序员都听说过设计模式,可是有不小一波的新手对于设计模式不是很清楚哟!今天就来聊聊设计模式的命令模式。
  所谓命令模式,我们首先来看一下什么是命令。通常情况下我们发出命令(信号),然后我们就看到了变化。这个具体是怎么变化的,我们作为命令的发出者很多时候不是很关心的。就像是老板一样只关心结果。
那我们来看看命令模式都有哪几部分组成!我们现在已电视为例子。首先,必须要有电视机也就是命令的接受者receiver。然后我们还必须要有一个遥控器,也就是有一个调度者invoker。当然了还少不了,我们的命令比如开机,比如播放等等一些列的,command。但是对于我们的程序员来说这些是不是够了呢好像不是很够!为什么因为如果命令没有一定的规范的话,那我们就应该定义一个接口,给出一定的规范。也就是相应的ICommand。那么最后我们应该也有一个客户端,也就是我们人,client。
   那么模式应该是怎么样的呢?
这里写图片描述

talk is cheap ,show your code。
package com.bj.contract;

/**
 * java 设计模式命令模式,命令接口,可以执行可以撤销!
 * */
public interface Icommand {
    void excute();
    void undo();
}
package com.bj.contract.impl;

import com.bj.contract.Icommand;
import com.bj.recivier.TestReceiver;
/**
 * 具体的命令,这个是用来解耦合的。持有接受者对象用来调用接受者来执行命令
 * */
public class PlayCommand implements Icommand {
    private TestReceiver testReceiver;

    public PlayCommand(TestReceiver testReceiver) {
        this.testReceiver = testReceiver;
    }

    @Override
    public void excute() {
       testReceiver.play();
    }

    @Override
    public void undo() {
       testReceiver.pause();
    }
}
package com.bj.Invoker;

import com.bj.contract.Icommand;
import com.bj.contract.enums.CommandCache;

import java.util.HashMap;
import java.util.Map;
/**
 * 命令的调度者,对客户端暴露接口。负责与客户端的交互,也就是命令的入口了
 * */
public class TvInvoker {
    private Map<String,Icommand> commandMap = new HashMap<>();
    private CommandCache commandEnum;
    //初始化,b把所有而已执行的命令都缓存一遍,客户端只需要根据命令的key来执行命令就可以了
    public void  init(){
        commandEnum=new CommandCache();
        commandEnum.init();
       for(Object key : commandEnum.getCommandHashMap().keySet()){
           commandMap.put(String.valueOf(key), (Icommand) commandEnum.getCommandHashMap().get(key));
       }
    }


    public Icommand removeCommand(String key){
        return commandMap.remove(key);
    }

    public void excute(){
        for(String string : commandMap.keySet()){
            commandMap.get(string).excute();
        }
    }
    public void excuteTCommadn(String key){
        commandMap.get(key).excute();
    }
    public void undo(){
        System.out.println("\"undo\" = " + "undo");
    }

}
package com.bj.recivier;

/**
 * 真正的命令接受者。所有的命令都有它执行。
 * */
public class TestReceiver {
    public void play(){
        System.out.println("播放!");
    }
    public void pause(){
        System.out.printf("暂停!");
    }
}
package com.bj.contract.enums;

import com.bj.contract.Icommand;
import com.bj.contract.impl.PlayCommand;
import com.bj.recivier.TestReceiver;
import lombok.Data;

import java.util.HashMap;

/**
 * 命令缓存,这里没有的命令不应该被执行!
 * */
@Data
public class CommandCache<T extends Icommand> {

    private HashMap<String,T> commandHashMap = new HashMap<String,T>();
    public void init(){
        commandHashMap.put("play", (T) new PlayCommand(new TestReceiver()));
    }

}
package com.bj.example;

import com.bj.Invoker.TvInvoker;
import com.bj.contract.Icommand;
import com.bj.recivier.TestReceiver;
/**
 * 测试命令模式
 * */
public class CommandExample {
    public static void main(String[] args) {
        TestReceiver testReceiver = new TestReceiver();
        TvInvoker tvInvoker = new TvInvoker();
        tvInvoker.init();
//        tvInvoker.excute();
        tvInvoker.excuteTCommadn("play");

    }
}

代码看完了,那么现在问题来了,这个设计模式的优点是什么?

  1. 松耦合,客户端和接受者之间已经解耦合完毕了。
  2. 动态控制简单,命令封装好以后队列化和日志就方便了。
  3. 扩展性非常好,因为前面的解耦合

说完了优点,再来说说应用场景

  • 原子事务,因为可以回退。
  • 状态条
  • 导航

最后附上自己的GitHub地址:
https://github.com/yunzhifei/designPatterns.git

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值