数学建模社区-数学中国

标题: Java设计模式——命令模式 [打印本页]

作者: 杨利霞    时间: 2020-4-24 18:12
标题: Java设计模式——命令模式

) E0 R* |! B% d) U9 i: QJava设计模式——命令模式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
9.png
0 y  L; j" b! c+ l$ ]( ]' XInvoker是调用者(司令员),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- {! fpublic 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 Zpublic 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+ u4 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' ~' t2 N# \+ ]2 q( i4 G6 x





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5