Java描述设计模式(20):命令模式
本文源码:GitHub·点这里 || GitEE·点这里
一、生活场景
1、场景描述
智能电脑的品牌越来越多,由此诞生了一款电脑控制的APP,万能遥控器,用户在使用遥控器的时候,可以切换为自家电视的品牌,然后对电视进行控制。
2、代码实现
public class C01_InScene { public static void main(String[] args) { TVClient tvClient = new TVClient() ; Remote remote = new RemoteApp(tvClient) ; UserClient userClient = new UserClient(remote) ; userClient.action("HM","换台"); } } /** * 遥控接口 */ interface Remote { void controlTV (String tvType,String task); } /** * 遥控器APP */ class RemoteApp implements Remote { private TVClient tvClient = null ; public RemoteApp (TVClient tvClient){ this.tvClient = tvClient ; } @Override public void controlTV(String tvType, String task) { tvClient.action(tvType,task); } } /** * 用户端 */ class UserClient { // 持有遥控器 private Remote remote = null ; public UserClient (Remote remote){ this.remote = remote ; } public void action (String tvType, String task){ remote.controlTV(tvType,task); } } /** * 电视端 */ class TVClient { public void action (String tvType, String task){ System.out.println("TV品牌:"+tvType+";执行:"+task); } }
二、命令模式
1、基础概念
命令模式属于对象的行为模式。命令模式把一个请求或者操作封装到一个对象中。把发出命令的动作和执行命令的动作分割开,委派给不同的对象。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行。
2、模式图解
3、核心角色
- 命令角色
声明所有具体命令类的抽象接口。
- 具体命令角色
定义接收者和行为之间的交互方式:实现execute()方法,调用接收者的相应操作 , 传递命令信息。
- 请求者角色
负责调用命令对象执行请求,相关的方法叫做行动方法。
- 接收者角色
执行请求。任何一个类都可以成为接收者,执行请求的方法叫做行动方法。
4、源码实现
public class C02_Command { public static void main(String[] args) { Receiver receiver = new Receiver(); Command command = new ConcreteCommand(receiver); Invoker invoker = new Invoker(command); invoker.action("卧倒"); } } /** * 命令角色 */ interface Command { // 执行方法 void execute(String task); } /** * 具体命令角色类 */ class ConcreteCommand implements Command { //持有相应的接收者对象 private Receiver receiver = null; public ConcreteCommand(Receiver receiver){ this.receiver = receiver; } @Override public void execute(String task) { //接收方来真正执行请求 receiver.action(task); } } /** * 请求者角色类 */ class Invoker { // 持有命令对象 private Command command = null; public Invoker(Command command){ this.command = command; } // 行动方法 public void action(String task){ command.execute(task); } } /** * 接收者角色类 */ class Receiver { // 执行命令操作 public void action(String task){ System.out.println("执行命令:"+task); } }
三、Spring框架应用
Spring框架中封装的JdbcTemplate类API使用到了命令模式。
1、JdbcOperations接口
public interface JdbcOperations { @Nullable <T> T execute(StatementCallback<T> var1) ; }
2、JdbcTemplate类
这里只保留模式方法的代码。
public class JdbcTemplate implements JdbcOperations { @Nullable public <T> T execute(StatementCallback<T> action) { try { T result = action.doInStatement(stmt); } catch (SQLException var9) { } finally { } } }
3、StatementCallback接口
@FunctionalInterface public interface StatementCallback<T> { @Nullable T doInStatement(Statement var1) ; }
四、命令模式总结
- 松散的耦合
命令模式使得命令发起者和命令执行者解耦,发起命令的对象完全不知道具体实现对象是谁。这和常见的MQ消息队列原理是类似的。
- 动态的控制
命令模式把请求封装起来,可以动态地对它进行参数化、队列化和等操作和管理,使系统更加的灵活。
- 良好的扩展性
命令发起者和命令执行者实现完全解耦,因此扩展添加新命令很容易。
五、源代码地址
GitHub·地址 https://github.com/cicadasmile/model-arithmetic-parent GitEE·地址 https://gitee.com/cicadasmile/model-arithmetic-parent
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
SwiftUI or Flutter ?
前言 相信每一个见到 SwiftUI 的开发者,都会立刻将这门船新的 UI 框架和 Flutter 联系到一起。是的,它们身上有太多太多相似的地方,相似的声明语法、实时热更新、跨平台(SwiftUI 仅仅跨 Apple 平台)等等,让羡慕了前端技术爆发的移动开发圈子也热闹了一回。那么 SwiftUI 和 Flutter 到底有什么相似和不同?它们又各有什么优缺点?以及最后,单就技术方向而言,谁才是未来跨平台方案的赢家呢? 语言 现代计算机语言越发趋于相似是一个不争的事实,因为每个语言的基本目标都相当的一致:简洁、灵活、安全、高性能。同时,各种语言的优异特性也都在被相互借鉴,更近一步减少了各个语言之间的鸿沟。 Swift 和 Dart 分别作为这两个 UI 框架的唯一官方语言,在语法层面的差别其实非常小,网上也有大量的文章来对比这两种语言的优劣性。我的使用体验和大部分人相似,就目前而言,Swift 和 Dart 各有优劣。 Swift 比 Dart 更加简洁。Swift 本身在语法层面已经比 Dart 要简洁很多,比如无需在句末添加;分号等。这一点在直接编写 SwiftUI 和 Flut...
- 下一篇
在python函数中默认参数的一些坑
一、默认参数 python为了简化函数的调用,提供了默认参数机制: 这样在调用pow函数时,就可以省略最后一个参数不写: 在定义有默认参数的函数时,需要注意以下: 必选参数必须在前面,默认参数在后; 设置何种参数为默认参数?一般来说,将参数值变化小的设置为默认参数。 python标准库实践 python内建函数: 函数签名可以看出,使用print('hello python')这样的简单调用的打印语句,实际上传入了许多默认值,默认参数使得函数的调用变得非常简单。 二、出错了的默认参数 引用一个官方的经典示例地址 def bad_append(new_item, a_list=[]): a_list.append(new_item) return a_list print(bad_append('1')) print(bad_append('2')) 这个示例并没有按照预期打印 ['1'] ['2'] 而是打印了: ['1'] ['1', '2'] 其实这个错误问题不在默认参数上,而是我们对于及默认参数的初始化的理解有误。 三、默认参数初始化 实际上,默认参数的值只在定义时计算一次,因此...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8安装Docker,最新的服务器搭配容器使用
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7安装Docker,走上虚拟化容器引擎之路
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS7设置SWAP分区,小内存服务器的救世主