命令模式
1.介绍
概念
命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
主要作用
将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。
解决的问题
在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
使用场景
认为是命令的地方都可以使用命令模式,比如: 1、GUI 中每一个按钮都是一条命令。 2、模拟 CMD。
(引用自菜鸟教程)
2.实现
背景
假设要创建一个客户端类,该客户端可以想其它客户端发送请求,也可以接受其它客户端的请求。我们利用命令模式对每个命令进行包装。
java实现
1.创建Order接口
public interface Order {
void execute();
}
2.创建Message类
public class Message {
private String username = "zhangsan";
private String password = "123456";
public void accept() {
System.out.println("Accept a message...");
System.out.println("username: " + username);
System.out.println("password: " + password);
}
public void send() {
System.out.println("Send a message...");
System.out.println("username: " + username);
System.out.println("password: " + password);
}
}
3.创建Request类,里面包含了Message
public class Request implements Order{
private Message message;
public Request(Message message) {
this.message = message;
}
@Override
public void execute() {
message.send();
}
}
- 创建Response类,里面包含了Message
public class Response implements Order{
private Message message;
public Response(Message message) {
this.message = message;
}
@Override
public void execute() {
message.accept();
}
}
5.创建Launcher类,可以发送Request或者接受Response
public class Launcher {
private ArrayList<Order> orderList = new ArrayList<Order>();
public void addOrder(Order order) {
orderList.add(order);
}
public void takeOrder() {
for (Order order : orderList) {
order.execute();
System.out.println("\n......\n");
}
orderList.clear();
}
}
6.创建测试类
public class CommandPatternDemo {
public static void main(String[] args) {
Message message = new Message();
Request request = new Request(message);
Response response = new Response(message);
Launcher launcher = new Launcher();
launcher.addOrder(request);
launcher.addOrder(response);
launcher.takeOrder();
}
}
7.运行结果
Send a message…
username: zhangsan
password: 123456
…
Accept a message…
username: zhangsan
password: 123456
…
golang实现
package CommandPattern
import "fmt"
// Order 创建order接口
type Order interface {
execute()
}
// Message 创建Message类
type Message struct {
username string
password string
}
func NewMessage() *Message {
return &Message{
username: "zhangsan",
password: "123456",
}
}
func (m *Message) accept() {
fmt.Println("Accept a message...")
fmt.Println("username: " + m.username)
fmt.Println("password: " + m.password)
}
func (m *Message) send() {
fmt.Println("Send a message...")
fmt.Println("username: " + m.username)
fmt.Println("password: " + m.password)
}
// Request 创建Request类,里面包含了Message
type Request struct {
message *Message
}
func NewRequest(message *Message) *Request {
return &Request{
message: message,
}
}
func (r *Request) execute() {
r.message.send()
}
// Response 创建Response类,里面包含了Message
type Response struct {
message *Message
}
func NewResponse(message *Message) *Response {
return &Response{
message: message,
}
}
func (r *Response) execute() {
r.message.accept()
}
// Launcher 创建Launcher类,可以发送Request或者接受Response
type Launcher struct {
orderList []Order
}
func (l *Launcher) addOrder(order Order) {
l.orderList = append(l.orderList, order)
}
func (l * Launcher) takeOrder() {
for i := 0; i < len(l.orderList); i++ {
l.orderList[i].execute()
fmt.Println()
fmt.Print("......")
fmt.Println()
}
l.orderList = append(l.orderList[:0])
}
package CommandPattern
import "testing"
func TestCommandPatternDemo(t *testing.T) {
message := NewMessage()
request := NewRequest(message)
response := NewResponse(message)
launcher := Launcher{}
launcher.addOrder(request)
launcher.addOrder(response)
launcher.takeOrder()
}