数学建模社区-数学中国

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

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

' P1 f: D( i) c; MJava设计模式——命令模式
% o$ u7 \; `/ V( ]" q! N2 m/ M- k8 ^# n- }2 L2 {. k
命令模式
! f- _/ L6 ?, B4 K/ s$ v9 ?8 f0 v' n2 L! _: b: A* K
命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行。这个过程好在,三者相互解耦,任何一方都不用去依赖其他人,只需要做好自己的事儿就行,司令员要的是结果,不会去关注到底士兵是怎么实现的。我们看看关系图:) d# \  g+ L6 U! r4 F2 p
9.png
6 N' w) z1 i: SInvoker是调用者(司令员),Receiver是被调用者(士兵),MyCommand是命令,实现了Command接口,持有接收对象,看实现代码:
+ U: j6 ]- L; E) Y4 j
4 ?( C! e' ?. t+ [% j; Q9 U& ~public interface Command {  2 ?! j, R4 p: l
    public void exe();  ) A2 K% a5 V2 R3 C
}  - [7 |( D* S1 d9 Y( `8 Q
public class MyCommand implements Command {  
; D6 c8 m- g: @: b$ ^% u; q7 A& l. p
  t  Y% F$ M! N7 q8 G- K' d    private Receiver receiver;  ; |2 S% Y6 I, O! M
3 o2 V& _( J2 v* u+ t/ ^# t
    public MyCommand(Receiver receiver) {  ; s! Z8 ^3 D3 J2 ^: k) o
        this.receiver = receiver;  
" Y4 C6 n' V0 Q( d+ t& E8 m+ X    }  
7 h& ^1 P* F4 E1 B. X/ e  S" o1 q3 o" o- y  p/ s
    @Override  8 a" x9 [# ]" j4 h. R4 F( Q& e$ L
    public void exe() {  / g, j& W/ S1 u' T; b0 ]
        receiver.action();  
6 A( Z$ C: X: y    }  
9 y* O# _$ N$ c  Z}  
7 r( S" b2 b/ O2 _' ppublic class Receiver {  
  P; ]. F+ Z; R2 e5 K3 d% U) P* v    public void action(){  
: t) H0 Y2 ]# T        System.out.println("command received!");  
  o. R/ W7 X9 q$ Q    }  
, g! T# ^' K) X7 F# R}  
$ p  K. n2 U/ S2 ^7 E4 Ppublic class Invoker {  . y% `, ^5 X) p9 A, P! ?
6 i3 v. M( n) C
    private Command command;  
' {# f  Y# w  \" `3 ^1 A( L* Z! i- v) a% R+ y& }: [$ @3 _7 g
    public Invoker(Command command) {  / M6 t# a9 ^: s! i( T4 N
        this.command = command;  
  w7 k+ A+ f3 x    }  
! U! q8 c6 i. ^# y( \, ~  G# [
  b8 L9 r1 _) z- Y- J    public void action(){  7 a; _9 n! _# \6 _! `3 [- c
        command.exe();  - T8 B! v: K, ?9 g- n: j# J* r7 f
    }  & r; H! s/ B4 }+ ?& k7 K& m& p! D& b
}  
8 H) ]- d% t1 a) hpublic class Test {  : k) w3 u1 w/ e3 d9 e' O, o
6 ]' ~0 k; u; v  {1 K1 `
    public static void main(String[] args) {  , Q' c! t+ e; `' b% u5 W6 @8 r
        Receiver receiver = new Receiver();  
2 n" _. @! j4 z  h8 p! x3 v        Command cmd = new MyCommand(receiver);  
) |2 l6 h1 }9 o% r        Invoker invoker = new Invoker(cmd);  
% w. }# I$ x4 [0 E! n/ T' I        invoker.action();  
& X9 b2 V2 B' U) S. F  Z; o, n! v    }    G* h$ i% d; }# r( o% a& m
}  1 ^9 O- Y! E! O5 F  o" T0 p8 @
/ v: p+ ]8 ^0 |
+ o% v. @- }# u/ L
这个很哈理解,命令模式的目的就是达到命令的发出者和执行者之间解耦,实现请求和执行分开,熟悉Struts的同学应该知道,Struts其实就是一种将请求和呈现分离的技术,其中必然涉及命令模式的思想!
/ ?( ?  k8 ^) m" f
& F: z6 ]% d9 q9 Q/ M介绍" w; A6 g' B5 I+ y! o; W' `
意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。
9 Z: r5 }' L+ }& n3 ^( x# }6 p$ j- O5 x+ u
' u: e+ p: {1 F7 r  |主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。' J" S+ k9 F% V9 H2 F1 r7 u7 v! N

+ ]/ n) x' D5 {7 ]& `2 H8 D何时使用:在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。3 _2 e& z6 }1 ]7 H& r+ `& ^

7 d! w5 i9 o0 u5 o. K- F; k如何解决:通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。" h! h4 j# \% M! X- u/ K

% v3 }5 b& s3 s关键代码:定义三个角色:1、received 真正的命令执行对象 2、Command 3、invoker 使用命令对象的入口
6 P( N( a' ^: Y: g2 Y) G9 v8 `
( U. \4 j8 f/ j3 a3 F1 v7 Q% b应用实例:struts 1 中的 action 核心控制器 ActionServlet 只有一个,相当于 Invoker,而模型层的类会随着不同的应用有不同的模型类,相当于具体的 Command。' k% `8 Y5 u9 E7 H' m$ Y: L1 }. W

$ g1 X! y$ @+ C/ K优点: 1、降低了系统耦合度。 2、新的命令可以很容易添加到系统中去。
$ i4 a- z- s6 T) g$ v0 N8 i* B6 b2 @6 B: M& H
缺点:使用命令模式可能会导致某些系统有过多的具体命令类。) d" B. _% f$ R' _

2 e* a- z* Q- A4 ]" U7 |3 o使用场景:认为是命令的地方都可以使用命令模式,比如: 1、GUI 中每一个按钮都是一条命令。 2、模拟 CMD。
, k9 [2 y7 K6 F2 [" E! q! [. r# e% y5 M* m8 Z' T/ S# T
注意事项:系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作,也可以考虑使用命令模式,见命令模式的扩展。( q0 \  g5 S: {& W; a, e
————————————————& j; s% s6 _8 Z; k. [2 _; |6 F7 t
版权声明:本文为CSDN博主「No_Game_No_Life_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
: C2 U4 ]1 i; U/ T! V9 R原文链接:https://blog.csdn.net/No_Game_No_Life_/article/details/85989272$ i- L4 w7 Z2 D

* y" L5 g5 Y, q+ p
1 l5 V3 @6 j2 n0 U




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