【设计模式】行为模式:命令模式

意图

它可将请求转换为一个包含与请求相关的所有信息的独立对象。该转换让你能根据不同的请求将方法参数化、延迟请求执行或将其放入队列中,且能实现可撤销操作。

例子

以下是 AWTK-MVVM 请求导航器打开指定的窗口的函数:

ret_t navigator_to(const char* target) {
  ret_t ret = RET_OK;
  navigator_request_t* req = NULL;
  return_value_if_fail(target != NULL && navigator() != NULL, RET_BAD_PARAMS);

  /* 根据字符串target创建对应命令 */
  req = navigator_request_create(target, NULL);
  return_value_if_fail(req != NULL, RET_OOM);

  /* 处理请求 */
  ret = navigator_handle_request(navigator(), req);
  object_unref(OBJECT(req));

  return ret;
}
ret_t navigator_handle_request(navigator_t* nav, navigator_request_t* req) {
  navigator_handler_t* handler = NULL;
  return_value_if_fail(nav != NULL && req != NULL, RET_BAD_PARAMS);

  handler = navigator_find_handler(nav, req->target);
  if (handler == NULL) {
    handler = navigator_find_handler(nav, NAVIGATOR_DEFAULT_HANDLER);
  }

  if (handler == NULL) {
    log_warn("not found %s\n", req->target);
  }
  return_value_if_fail(handler != NULL, RET_NOT_FOUND);

  return navigator_handler_on_request(handler, req);
}
static ret_t navigator_handler_awtk_on_request(navigator_handler_t* handler,
                                               navigator_request_t* req) {
  /* 根据命令选择处理方式 */
  if (tk_str_ieq(req->target, NAVIGATOR_REQ_CLOSE)) {
    const char* name = object_get_prop_str(OBJECT(req->args), NAVIGATOR_ARG_NAME);
    widget_t* win = widget_child(window_manager(), name);
    return window_manager_close_window_force(window_manager(), win);
  } else if (tk_str_ieq(req->target, NAVIGATOR_REQ_BACK)) {
    return window_manager_back(window_manager());
  } else if (tk_str_ieq(req->target, NAVIGATOR_REQ_HOME)) {
    return window_manager_back_to_home(window_manager());
  }

  if (!(req->open_new)) {
    widget_t* wm = window_manager();
    widget_t* target_win = widget_child(wm, req->target);

    if (target_win != NULL) {
      widget_t* curr_win = window_manager_get_top_window(wm);
      return window_manager_switch_to(wm, curr_win, target_win, req->close_current);
    }
  }

  return awtk_open_window(req);
}

命令模式结构

命令模式结构图

小结

适合应用场景

  • 需要通过操作来参数化对象。

  • 需要将操作放入队列中、操作的执行或者远程执行操作(命令序列化(转字符串))。

  • 需要实现操作回滚功能(实现已执行操作的历史记录功能:备份状态或执行反向操作)。

优点

  • 单一职责原则,你可以解耦触发和执行操作的类。

  • 开闭原则,你可以在不修改已有客户端代码的情况下在程序中创建新的命令。

  • 你可以实现撤销和恢复功能。

  • 你可以实现操作的延迟执行。

  • 你可以将一组简单命令组合成一个复杂命令。

缺点

  • 代码可能会变得更加复杂, 因为你在发送者和接收者之间增加了一个全新的层次。

参考

22种设计模式:refactoringguru.cn/design-patterns
AWTK-MVVM :github.com/zlgopen/awtk-mvvm
《设计模式:可复用面向对象软件的基础》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值