å‘½ä»¤æ¨¡å¼æ˜¯ä¸€ä¸ªå¾ˆæœ‰æ´»åŠ›çš„è®¾è®¡æ¨¡å¼ï¼Œå®ƒçš„å‡ é¡¹ç‰¹ç‚¹å…·æœ‰å¾ˆå¥½çš„åˆ©ç”¨ä»·å€¼ï¼Œæˆ‘ä»¬å¯ä»¥é€šè¿‡æ¼”å˜è¯¥æ¨¡å¼ä¸ºè®¸å¤šé—®é¢˜æ‰¾åˆ°è§£å†³æ–¹æ¡ˆã€‚
先教科书å¼åœ°æ‘†å‡ºå‘½ä»¤æ¨¡å¼çš„UML图,并有请模å¼ä¸å„角色登场。看过之åŽè¯·ä¸€å®šè®°ä½ï¼Œä¸èƒ½æ•™ç§‘书å¼åœ°èƒŒè¯µå®ƒä»¬æˆ–使用它们ï¼ä¸èƒ½æ‹˜æ³¥äºŽæ•™ç§‘书å¼çš„命令模å¼è¡¨è¿°ï¼Œå‘挥其特点和æ€è·¯æ‰æ˜¯æ£é€”ã€‚è®¾è®¡æ¨¡å¼æç‚¼è‡ªé—®é¢˜åˆç”¨æ¥äº¤æµå¹¶é‡å¤è§£å†³é—®é¢˜ï¼Œæ‰€ä»¥ä¸ºå…·ä½“的问题去ç†è§£å¹¶æ‰“é€ å®ƒå§ã€‚
1ã€æ‰¹é‡æ‰§è¡Œå‘½ä»¤
通过实现Command接å£ï¼Œå„实现类实例å¯èšåˆåœ¨ä¸€èµ·å¹¶è¢«InvokeréåŽ†ï¼Œä¾æ¬¡æ‰§è¡Œå„命令的Executeæ–¹æ³•ï¼Œè¾¾åˆ°æ‰¹é‡æ‰§è¡Œå‘½ä»¤çš„目的。如果有需è¦çš„è¯ï¼Œæ¯ä¸ªå‘½ä»¤æ‰§è¡Œçš„返回结果都å¯åœ¨Invoker处收集到。
è¿™é‡Œä¸¾å‚æ•°æ£€æŸ¥çš„例å。如ç›é€‰é¢è¯•è€…ä¿¡æ¯æ—¶ï¼Œéœ€è¦ä¸€ä¸€æ£€æŸ¥å„关键傿•°æ˜¯å¦æ»¡è¶³è¦æ±‚:emailè¦éªŒè¯æ ¼å¼ï¼Œå¹´é¾„段è¦ç¬¦åˆé™åˆ¶ï¼Œå„é¡¹è¯„åˆ†è¾¾åˆ°ç›¸åº”è¦æ±‚ç‰ç‰ã€‚
- æ™®é€šå†™æ³•ä»€ä¹ˆæ ·å„¿ï¼Ÿè‹¥å¹²å«æœ‰â€œValidatingXXXâ€æ–¹æ³•çš„ifè¯å¥å½¢æˆä¸‘陋的排比å¥ï¼Œå‡¡æ˜¯è¿”回值出现false,一律终æ¢ä¹‹åŽçš„æ£€æŸ¥å¹¶å–消åŽç»çš„业务逻辑执行。
- 命令模å¼å¸¦ç»™ä½ 清净。对ç€å›¾ï¼ŒClient把典型验è¯é€»è¾‘包å«åœ¨è‹¥å¹²ConcreteCommand对象当ä¸ï¼Œå½¢æˆå‘½ä»¤é›†åˆäº¤ç»™Invoker,å†å°†é¢è¯•者信æ¯å¯¹è±¡å¡«å…¥ï¼Œç”±Invoker执行å„命令的Execute方法分别去验è¯è¾“å…¥å¯¹è±¡çš„å‚æ•°ï¼ŒInvokerå¯éšæ—¶è§‚å¯Ÿåˆ°è¿”å›žfalse的命令执行结果并终æ¢åŽç»é€»è¾‘。Receiver在上述过程ä¸å¯ä»¥ä¸å¿…å‡ºçŽ°ï¼Œå› ä¸ºè¿˜æ²¡æœ‰å‡ºçŽ°éœ€è¦è®©å…¶ä»–æŸå„对象特地åšç‚¹ä»€ä¹ˆçš„æ—¶å€™ã€‚
2ã€å‘½ä»¤å¯¹è±¡çš„å˜åœ¨æ„Ÿ
ç‹ä¹‰åœ°è®²ï¼Œå‘½ä»¤å°±æ˜¯å¸Œæœ›å®Œæˆçš„æ„å›¾ã€‚è°ƒç”¨æ–¹æ³•æ˜¯è¾¾åˆ°æ„å›¾çš„è¿‡ç¨‹ï¼Œå¯æƒœè¿™ä¸ªè¿‡ç¨‹ä»ŽæœŸæœ›æ‰§è¡Œåˆ°å¼€å§‹æ‰§è¡Œæ˜¯çž¬é—´å¯åŠ¨çš„ï¼Œæ–¹æ³•æ‰§è¡Œå®Œæ¯•å‘½ä»¤çš„æ•ˆæžœä¹Ÿå°±ç»“æŸäº†ï¼ŒçƒŸæ¶ˆäº‘散。当我们将命令寄居在对象上的时候,这个æ„图的生命周期å¯è§äº†ã€‚
- 从å‘布命令到命令被执行,对象å¯ä»¥ç‰å¾…,于是时间上的耦åˆè¢«è§£å¼€äº†ã€‚我们å¯ä»¥ä¸ºåˆ›å»ºçš„å‘½ä»¤å¯¹è±¡è®¾ç½®å»¶æ—¶ï¼Œè®©éœ€è¦æ·±å¤œæ‰§è¡Œçš„程åºåœ¨ç™½å¤©å°±å‘布给命令执行引擎。
- ä»Žå‚æ•°çš„æŽ¥æ”¶ã€éªŒè¯åˆ°å‘½ä»¤æ‰§è¡Œï¼Œå·¥ä½œå¯ä»¥åˆ†æ´¾ï¼Œæ‰€ä»¥å¯¹è±¡å®žä½“上的耦åˆè¢«è§£å¼€äº†ã€‚我们å¯ä»¥ä¸ºConcreteCommand类对象指定多个Receiver,让它们分别完æˆå‚数的验è¯å’Œæ„图的执行。
æ¯«æ— ç–‘é—®ï¼Œé¢å‘对象的世界里,方法也å¯è¢«è§†ä¸ºå¯¹è±¡ã€‚Function Object被多ç§ç¼–程è¯è¨€æ”¯æŒç€ä¸”ä¸è¯´ï¼Œå°±è¿žæˆ‘所å¦çš„第一门编程è¯è¨€â€”—Cè¯è¨€ï¼Œä¹Ÿèƒ½ä»¥å‡½æ•°æŒ‡é’ˆçš„æ–¹å¼å°†æ„图指定并ä¿ç•™ä¸‹æ¥ï¼Œä¹‹åŽæ‰§è¡Œã€‚如果情况适åˆçš„è¯ï¼Œä¹Ÿå¯ä»¥è¯•用它们完æˆå‘½ä»¤æ¨¡å¼çš„æ€æƒ³ï¼Œä¸è¿‡ä¸€ä¸ªå‘½ä»¤å®žçŽ°ç±»è¿˜æ˜¯åœ¨æä¾›è¾…助方法以åŠå®žçŽ°ç»Ÿä¸€æŽ¥å£ä¸Šæœ‰æ›´å¤§çš„æ“ä½œç©ºé—´ã€‚
3ã€å‘½ä»¤çš„æ‰§è¡Œå¯¹å‘å¸ƒè€…é€æ˜Ž
å‘½ä»¤æ¨¡å¼æœ€åŸºæœ¬çš„æ¨¡åž‹ï¼Œåªæœ‰commander类和若干command实现类,对象之间是1对N的关系。其ä¸ï¼Œcommander对象负责在å„ç§æƒ…形下å‘出å„ç§å‘½ä»¤ï¼Œå³åŒæ¥æˆ–异æ¥åœ°å®‰æŽ’command对象执行Execute方法;command对象在得到执行许å¯åŽï¼Œå…¨æƒæŽ¥ç®¡å…·ä½“执行过程。
好处是显而易è§çš„ã€‚å°±åƒæŽŒæŽ§å…¨å±€çš„æŒ‡æŒ¥å®˜ï¼Œäº†è§£äº†å„ç§å‘½ä»¤èƒ½è¾¾åˆ°çš„æ„å›¾ï¼ŒæŒ‰éœ€å‘出命令就是了,ä¸éœ€è¦çŸ¥é“是è°åˆæ˜¯å¦‚何让这æ¡å‘½ä»¤è½åˆ°å®žå¤„ã€‚æ˜¯ä¸æ˜¯æƒ³åˆ°äº†æ‰‹æ¡é¥æŽ§å™¨é‚£ä¸€åˆ»çš„自己呢?
命令模å¼å¯¹â€œäº‹ä»¶ï¼å“åº”â€æ¨¡åž‹æœ‰è‰¯å¥½çš„æ”¯æŒã€‚我们常使用dispatcherå°†å“应函数与事件特å¾ç›¸å…³è”,如MVCä¸ç”±routerå°†Requestæ˜ å°„åˆ°ControlleræŸæ–¹æ³•上,将对å“应函数的调用æ¢ä½œå‘½ä»¤çš„å‘出,就æ¢åˆ°äº†å‘½ä»¤æ¨¡å¼çš„æ€ç»´ä¸Šã€‚ç»¼åˆä¸Šä¸€èŠ‚å¯¹å‘½ä»¤å¯¹è±¡çš„é˜è¿°ï¼Œ
- 我们å¯ä»¥åœ¨å‘½ä»¤å‘出时立å³è°ƒç”¨å…¶Execute方法,这与直接调用å“åº”å‡½æ•°ç‰æ•ˆï¼›æˆ‘们也å¯åˆ©ç”¨å‘½ä»¤å¯¹è±¡çš„é•¿å‘½ï¼Œä»¥å¼‚æ¥æ–¹å¼æŽ¨è¿Ÿæ‰§è¡Œå‘½ä»¤çš„æ–¹æ³•ï¼›
- 我们ä¸éœ€è¦åœ¨dispatcher上就知é“è¦è°ƒç”¨å“ªä¸ªå¯¹è±¡çš„哪ç§è¡Œä¸ºä½œä¸ºå“应,åªéœ€è¦çŸ¥é“å‘出那类命令。
- 我们å¯ä»¥åˆ©ç”¨å‘½ä»¤å¯¹è±¡å¯¹å¤–暴露接å£çš„一致性,借用命令对象作为Wrapper包装个性ä¸ä¸€çš„å“应函数,dispatcheræ›´è½»é‡å’Œæ•´æ´ã€‚
4ã€å‘½ä»¤çš„追踪和undo
命令模å¼ä»¥å¯¹è±¡ä¸ºç²’度管ç†å‘½ä»¤ï¼Œå‘½ä»¤å¯¹è±¡åˆ›å»ºåŽå¹¶æœªç«‹å³æ‰§è¡Œï¼Œå‘½ä»¤æ‰§è¡Œå®Œæ¯•åŽå¯¹è±¡å´ä»æœªé”€æ¯ã€‚我们å¯å°†æœªæ‰§è¡Œçš„å‘½ä»¤å…¥é˜Ÿå˜æˆåºåˆ—,将已执行的命令ä¿å˜ä¸ºåކå²ï¼Œè¿™æ ·æ¥è¿½è¸ªå‘½ä»¤ã€‚
命令模å¼ä¸å‘½ä»¤è¢«å®žçŽ°ç±»æ‰€å®šä¹‰ï¼Œä¸ºå…¶å…³è”除ExecuteæŽ¥å£æ–¹æ³•之外的方法很方便,其ä¸å¾ˆæœ‰æ„义的一个æ€è·¯æ˜¯ä¸ºå¯é€†å‘½ä»¤æ·»åŠ undo方法。å‰é¢è¯´åˆ°å¯è¿½è¸ªå·²æ‰§è¡Œçš„命令,那么对一个全部实现了undo方法的命令åºåˆ—ï¼Œå°†æ¯æ¡å‘½ä»¤æ‰§è¡ŒåŽå…¥æ ˆï¼Œå³å¯éšæ—¶é€šè¿‡å‡ºæ ˆå¹¶æ‰§è¡Œundo的方å¼å®žçŽ°å›žæ»šã€‚ï¼ˆå¦‚æžœæ²¡æœ‰undo方法,那么实现回滚就æ„味ç€è¦ä»Žä¸€ä¸ªèµ·ç‚¹å¼€å§‹å°†ä¹‹åŽåˆ°è®°å½•䏿Ÿç‚¹ä¹‹å‰çš„æ‰€æœ‰å‘½ä»¤é‡æ–°æ‰§è¡Œã€‚)
用两个应用实例æ¥è¯´æ˜Žå®ƒçš„优势。
- 事务。如果将事务ä¸çš„æ‰§è¡Œæ¥éª¤åˆ‡åˆ†ä¸ºè‹¥å¹²è¿žç»çš„命令,那么事务的开始就是这一命令åºåˆ—的执行开始,事务æˆåŠŸå®Œæˆçš„æ ‡å¿—是最åŽä¸€ä¸ªå‘½ä»¤æˆåŠŸæ‰§è¡Œï¼Œè€Œäº‹åŠ¡å¤±è´¥åŽå›žæ»šåˆ™æ˜¯ä»Žå¤±è´¥ç‚¹å¼€å§‹å°†å‰é¢çš„命令按åºåˆ—å€’åºæ‰§è¡Œundo方法直至开始。
- 增é‡åž‹æ“作的redo与undo。如使用Photoshop对图片åšå¤„ç†ï¼Œæ¯æ¥æ“作都是一个Command,由对应的工具作为其Receiver在上一æ“作完æˆåŽçš„图åƒä¸Šåšå‡ºä¿®æ”¹ï¼Œå¹¶å¦‚实记录该CommandåŠç›¸å…³å‚数在历å²åˆ—表ä¸ã€‚我们å¯ä»¥ä½¿ç”¨undo回滚当å‰ä¸€æ¥çš„修改,或å†ä½¿ç”¨redo应用它;当点选历å²åˆ—表ä¸çš„æŸé¡¹æ—¶ï¼Œè¯¥é¡¹ä¹‹åŽçš„åŽ†å²æ“ä½œè¢«ä¾æ¬¡undo,å³å›žæ»šåˆ°æŒ‡å®šä½ç½®ã€‚
5ã€å‘½ä»¤é˜Ÿåˆ—与Active Object模å¼
å‘½ä»¤æ¨¡å¼æ»¡è¶³Active Object模å¼çš„å…è¦ç´ :
- 供外部访问的代ç†ï¼Œèƒ½æž„é€ è¯·æ±‚å¹¶å…¥é˜Ÿâ€”â€”Clientï¼›
- 所有Active Object实现了统一的接å£â€”—Command::Executeï¼›
- 待处ç†çš„请求åºåˆ———CommandQueueï¼›
- 维护请求åºåˆ—并安排处ç†é˜Ÿé¦–请求的引擎——ActiveObjectEngineï¼›
- Active Objectä¸å¤„ç†è¯·æ±‚的实现者或实现方法——Receiverï¼›
- 一ç§å°†ç»“æžœå‘å¤–ä¼ è¾¾çš„ç»“æžœè¿”å›žæˆ–å‡½æ•°å›žè°ƒæ–¹å¼â€”—Receiverï¼›
å®žçŽ°çš„æ ¸å¿ƒæ€æƒ³æ˜¯ï¼šåœ¨æ‰§è¡Œä¸çš„é˜Ÿé¦–å‘½ä»¤æœ‰èƒ½åŠ›å°†æ–°å‘½ä»¤åŠ è‡³é˜Ÿåˆ—å°¾ï¼›ç‰å¾…事件或资æº(如时间片)çš„æ–¹å¼æ˜¯ä»¥æŒç»æŸ¥è¯¢çš„æ–¹å¼ä¸æ–å°†ä»ä¸æ»¡è¶³æ‰§è¡Œæ¡ä»¶çš„é˜Ÿé¦–å‘½ä»¤æ·»åŠ è‡³é˜Ÿå°¾ã€‚è¿˜æœ‰ï¼ŒCPU时钟与实时时钟是ä¸åŒæ¥çš„,利用延时检查作为调度æ¡ä»¶ä¼šå‡ºçŽ°ä¸€å®šä¸ç¡®å®šæ€§ï¼Œè¿™ç§æ€§è´¨æ£æ˜¯å¤šçº¿ç¨‹ç³»ç»Ÿçš„特点。
Active Objectæ¨¡å¼æ˜¯å®žçŽ°å¤šçº¿ç¨‹è°ƒåº¦çš„ä¸€ç§å…¸åž‹æ–¹å¼ã€‚利用延时ç‰å¾…çº¿ç¨‹çš„æ—¶é—´ç‰‡ï¼Œåœ¨æ—¶é—´ç‰‡è½®è½¬åˆ°æ—¶å¼€å§‹å¯¹åº”çº¿ç¨‹çš„ä¸´ç•Œèµ„æºæ£€æŸ¥ï¼Œæ»¡è¶³è¿è¡Œæ¡ä»¶æ—¶å”¤é†’线程。延时长çŸçš„设置å¯åæ˜ çº¿ç¨‹çš„éžæŠ¢å å¼ä¼˜å…ˆçº§ã€‚
Active Object模å¼å¯ç”¨æ¥ä»¥å•çº¿ç¨‹æ¨¡æ‹Ÿå¤šçº¿ç¨‹ç³»ç»Ÿã€‚è¿™é‡Œå¯¹æ¨¡æ‹Ÿçš„çº¿ç¨‹æ˜¯æœ‰è¦æ±‚的,需è¦RTC(run-to-completionï¼‰çº¿ç¨‹ã€‚è¿™é‡Œåˆ©ç”¨åˆ°äº†å‘½ä»¤ä¸€ç»æ‰§è¡Œå°±ä¸€å®šå¾—完æˆçš„æ€§è´¨ï¼Œå¯ä»¥çœ‹åˆ°ï¼Œå¤šä¸ªå‘½ä»¤å…¶å®žæ˜¯æœ‰åŒæ¥å®Œæˆæ‰§è¡Œçš„å…³ç³»ã€‚è¿™æ ·åªéœ€å•一的工作者线程,在ä¸åŒæ—¶é—´æ®µæ‰§è¡Œä¸åŒçš„任务,é¿å…了为å„个任务分别分é…å„自的è¿è¡Œæ—¶å †æ ˆï¼Œè¿™åœ¨å†…å˜å—é™ç³»ç»Ÿä¸æ˜¯ä¸€ä¸ªä¸é”™çš„节约。
Tuo
2011-06-08 at 09:50
收录了~~