数学建模社区-数学中国
标题:
Java设计模式——命令模式
[打印本页]
作者:
杨利霞
时间:
2020-4-24 18:12
标题:
Java设计模式——命令模式
) E0 R* |! B% d) U9 i: Q
Java设计模式——命令模式
2 C# U) }# ?% `( m
4 q/ E- y) L* n5 {
命令模式
8 `- B; L( H/ b% d0 R, i
& X% s* ?# R; M4 p* Y6 x0 m
命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行。这个过程好在,三者相互解耦,任何一方都不用去依赖其他人,只需要做好自己的事儿就行,司令员要的是结果,不会去关注到底士兵是怎么实现的。我们看看关系图:
5 k( |; ^" ~/ m3 O
2020-4-24 18:11 上传
下载附件
(57.13 KB)
0 y L; j" b! c+ l$ ]( ]' X
Invoker是调用者(司令员),Receiver是被调用者(士兵),MyCommand是命令,实现了Command接口,持有接收对象,看实现代码:
B$ ~' ]! Z* t1 A* i! s1 y
/ K9 a5 K8 p; z+ r) n
public interface Command {
; r- T' g2 w, g; U
public void exe();
( B: h+ C+ x) y3 B
}
9 i% R& c- {! f
public class MyCommand implements Command {
, G& b1 O5 A. r+ V) G
+ m1 R+ ~* f8 @' K
private Receiver receiver;
; R) [8 V7 D2 Y) g' j
/ F( d7 _% F- Q+ W1 X1 _
public MyCommand(Receiver receiver) {
! a: ]! @' T. a! H( w1 W0 l
this.receiver = receiver;
6 a6 m6 \6 M7 F' m. _
}
+ e9 [/ y- }9 Q4 X) e) V8 Z% ~) R* b
4 T5 @- E' [ U2 t
@Override
( P* B* I; z* r( r, F, _
public void exe() {
+ S0 O' t4 \8 |7 i. b
receiver.action();
+ a& @8 Z; c" Q+ z
}
: u5 ]: \' z- F" c) [; Q* {4 d7 K
}
% ~) R1 Q( l! K J3 k' j
public class Receiver {
5 a. d2 s$ ^+ x4 f, ]" m+ W
public void action(){
' J% }2 |( {+ T5 b* x
System.out.println("command received!");
l) Q8 z+ e. i% t7 x C# k2 W" F
}
2 L1 {& V* @+ P! c& J( y- }& Z
}
% O8 G6 L: @8 Z
public class Invoker {
+ n5 k1 [; I1 k D% I( X
0 N* ], o$ G* r5 ]
private Command command;
. l1 O/ n- X5 W; ^+ C
& u J7 c# P, \5 h# B
public Invoker(Command command) {
: @) T) q) J7 \
this.command = command;
% q4 ?' m+ p. J' V, G( h1 {
}
7 V* ~/ {3 y: R1 v' Z4 h
. S( m# L7 ~5 `7 k
public void action(){
* y( e5 o7 h( k
command.exe();
4 c, o( v3 J+ N
}
# m' x6 |8 s& _' Q- i
}
; S1 t, K7 N' S" \
public class Test {
' D) N2 k. f9 N! ?
9 L# G( E# W6 P$ f- I
public static void main(String[] args) {
7 N% g* D6 D/ }/ Z) z. q* [
Receiver receiver = new Receiver();
/ O& [" e2 G8 [8 T
Command cmd = new MyCommand(receiver);
7 L% ]9 C; E( H
Invoker invoker = new Invoker(cmd);
) L7 {6 e! C* t# K& j0 J7 z
invoker.action();
9 _6 {' q; V H, x
}
% J& D E& b4 S2 }
}
1 i7 t$ i1 ~+ @; ~# N
* j" o/ }4 X) x: W/ m7 {3 {
! c3 ~7 I# O/ p& C3 Y! _
这个很哈理解,命令模式的目的就是达到命令的发出者和执行者之间解耦,实现请求和执行分开,熟悉Struts的同学应该知道,Struts其实就是一种将请求和呈现分离的技术,其中必然涉及命令模式的思想!
4 E7 a/ D9 y/ Y2 X# k9 v8 T; o
- t1 A6 P- F4 L L
介绍
! T* Q' t4 L" W
意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。
: ~) U2 }( a/ t+ u
4 a) D" e! b2 a( M
主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
# u1 W2 X" g& u! v
2 E0 Z, C; P/ T& K6 p
何时使用:在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。
% T4 D. q5 I, \$ e
6 O4 F& C9 C: {$ A V6 E
如何解决:通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。
/ x. S0 i- s" L* O
, L/ @$ c0 s) a, Q) m# \" y' C% m' ^& \# R
关键代码:定义三个角色:1、received 真正的命令执行对象 2、Command 3、invoker 使用命令对象的入口
" i% J1 S' B$ ]1 Z* W; @$ j
2 F+ D2 z, ~9 i4 H9 \& X
应用实例:struts 1 中的 action 核心控制器 ActionServlet 只有一个,相当于 Invoker,而模型层的类会随着不同的应用有不同的模型类,相当于具体的 Command。
1 s' l. b+ {$ Q6 n. l" h1 q
: ~ b2 _: s( a* F6 o$ E1 M
优点: 1、降低了系统耦合度。 2、新的命令可以很容易添加到系统中去。
3 N! _. a, }6 a; y, x, G4 ~8 `
4 A3 Y# `8 d; {3 z" ~& }) P
缺点:使用命令模式可能会导致某些系统有过多的具体命令类。
% k) K5 q( e3 q3 J+ \
2 |/ @) p) q) Q
使用场景:认为是命令的地方都可以使用命令模式,比如: 1、GUI 中每一个按钮都是一条命令。 2、模拟 CMD。
" f0 I0 F5 _1 r( d* Y
- D: a* O4 A& J- Q2 ?. ^
注意事项:系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作,也可以考虑使用命令模式,见命令模式的扩展。
# h% m/ z3 R% S2 Q) \, {( z
————————————————
5 }9 H2 Q+ q2 E3 a: A9 _: ]3 v
版权声明:本文为CSDN博主「No_Game_No_Life_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
7 F5 B# X C3 u! k& d
原文链接:https://blog.csdn.net/No_Game_No_Life_/article/details/85989272
P9 s: P9 p+ X9 i% K A
, |; ^6 w' ~' t
2 N# \+ ]2 q( i4 G6 x
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5