<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    love fish大鵬一曰同風起,扶搖直上九萬里

    常用鏈接

    統(tǒng)計

    積分與排名

    friends

    link

    最新評論

    Java中的模式 --- 命令模式的(實現(xiàn),功能,使用場合)及如何配合其它模式使用命令模式 (轉(zhuǎn))

    一,命令模式的實現(xiàn):
    命令模式里邊一般都有以下幾個角色:客戶端,請求者,命令接口,命令實現(xiàn),接受者,
    下邊是簡單命令模式的實現(xiàn)代碼實現(xiàn):
    ?1public?class?Client{
    ?2????public?static?void?main(String[]?args){
    ?3????????Receiver?receiver?=?new?Receiver();
    ?4????????Command?commandOne?=?new?ConcreteCommandOne(receiver);
    ?5????????Command?commandTwo?=?new?ConcreteCommandTwo(receiver);
    ?6????????Invoker?invoker?=?new?Invoker(commandOne,commandTwo);
    ?7????????invoker.actionOne();
    ?8????????invoker.actionTwo();
    ?9????}

    10}

    11public?class?Invoker{
    12????private?Command?commandOne;
    13????private?Command?commandTwo;
    14????public?Invoker(Command?commandOne,Command?commandTwo){
    15????????this.commandOne?=?commandOne;
    16????????this.commandTwo?=?commandTwo;
    17????}

    18????public?void?actionOne(){
    19????????commandOne.execute();
    20????}

    21????public?void?actionTwo(){
    22????????commandTwo.execute();
    23????}

    24}

    25public?interface?Command{
    26????void?execute();
    27}

    28public?class?ConcreteCommandOne?implements?Command{
    29????private?Receiver?receiver
    30????public?ConcreteCommandOne(Receiver?receiver){
    31????????this.receiver?=?receiver;
    32????}

    33????public?void?execute(){
    34????????receiver.actionOne();
    35????}

    36}

    37public?class?ConcreteCommandTwo?implements?Command{
    38????private?Receiver?receiver
    39????public?ConcreteCommandTwo(Receiver?receiver){
    40????????this.receiver?=?receiver;
    41????}

    42????public?void?execute(){
    43????????receiver.actionTwo();
    44????}

    45}

    46public?class?Receiver{
    47????public?Receiver(){
    48????????//
    49????}

    50????public?void?actionOne(){
    51????????System.out.println("ActionOne?has?been?taken.");
    52????}

    53????public?void?actionTwo(){
    54????????System.out.println("ActionTwo?has?been?taken.");
    55????}

    56}

    二,命令模式的功能,好處,或者說為什么使用命令模式?
    上邊的代碼是否看起來很傻呢,本來可以這樣簡單實現(xiàn)的:
    ?1public?class?Client{
    ?2????public?static?void?main(String[]?args){
    ?3????????Receiver?receiver?=?new?Receiver();
    ?4????????receiver.actionOne();
    ?5????????receiver.actionTwo();
    ?6????}

    ?7}

    ?8public?class?Receiver{
    ?9????public?Receiver(){
    10????????//
    11????}

    12????public?void?actionOne(){
    13????????System.out.println("ActionOne?has?been?taken.");
    14????}

    15????public?void?actionTwo(){
    16????????System.out.println("ActionTwo?has?been?taken.");
    17????}

    18}


    看多簡潔,如果是像上邊如此簡單的需求,這個才應該是我們的選擇,但是有些情況下這樣的寫法不能解決的,
    或者說解決起來不好,所以引入命令模式.
    (1)我們須要Client和Receiver同時開發(fā),而且在開發(fā)過程中分別須要不停重購,改名
    (2)如果我們要求Redo ,Undo等功能
    (3)我們須要命令不按照調(diào)用執(zhí)行,而是按照執(zhí)行時的情況排序,執(zhí)行
    (4)開發(fā)后期,我們發(fā)現(xiàn)必須要log哪些方法執(zhí)行了,如何在盡量少更改代碼的情況下實現(xiàn).并且漸少重復代碼
    (5)在上邊的情況下,我們的接受者有很多,不止一個
    解決辦法:
    情況一,我們可以定義一個接口,讓Receiver實現(xiàn)這個接口,Client按照接口調(diào)用。
    情況二,我們可以讓Receiver記住一些狀態(tài),例如執(zhí)行前的自己的狀態(tài),用來undo,但自己記錄自己的狀態(tài)
    ?實現(xiàn)起來比較混亂,一般都是一個累記錄另一個類的狀態(tài).
    情況三,很難實現(xiàn)
    情況四,,我們須要在每個Action,前后加上log
    情況五,相對好實現(xiàn),但是再加上這個,是否感覺最終的實現(xiàn)很混亂呢
    好,我們再來看看命令模式,在命令模式中,我們增加一些過渡的類,這些類就是上邊的命名接口和命令實現(xiàn),
    這樣就很好的解決了情況一,情況二。我們再加入一個Invoker,這樣情況三和情況四就比較好解決了。

    如下加入Log和排序后的Invoker

    ?1public?class?Invoker{
    ?2????private?List?cmdList?=?new?ArrayList();
    ?3????public?Invoker(){
    ?4????}

    ?5????public?add(Command?command){
    ?6????????cmdList.add(command);
    ?7????}

    ?8????public?remove(Command?command){
    ?9????????cmdList.remove(command);
    10????}

    11????public?void?action(){
    12????????Command?cmd;
    13????????while((cmd?=getCmd())?!=?null){
    14????????????log("begin"+cmd.getName());
    15????????????cmd.execute();
    16????????????log("end"+cmd.getName());????????
    17????????}

    18????}

    19????public?Command?getCmd(){
    20????????//按照自定義優(yōu)先級,排序取出cmd
    21????}

    22}

    23public?class?Client{
    24????public?static?void?main(String[]?args){
    25????????Receiver?receiver?=?new?Receiver();
    26????????Command?commandOne?=?new?ConcreteCommandOne(receiver);
    27????????Command?commandTwo?=?new?ConcreteCommandTwo(receiver);
    28????????Invoker?invoker?=?new?Invoker();
    29????????invoker.add(commandOne);
    30????????invoker.add(commandTwo);
    31????????iinvoker.action();
    32????}

    33}


    三,命令模式與其它模式的配合使用:
    1,看上邊的Invoker的實現(xiàn)是否很像代理模式呢,Invoker的這種實現(xiàn)其實就是一種代理模式。

    2,需求:有個固定命令組合會多次被執(zhí)行
    ?? 解決:加入合成模式,實現(xiàn)方法如下,定義一個宏命令類:

    ?1public?class?MacroCommand?implements?Command{
    ?2????private?List?cmdList?=?new?ArrayList();
    ?3????public?add(Command?command){
    ?4????????cmdList.add(command);
    ?5????}

    ?6????public?remove(Command?command){
    ?7????????cmdList.remove(command);
    ?8????}

    ?9????public?void?execute(){
    10????????Command?cmd;
    11????????for(int?i=0;i<cmdList.size();i++){
    12????????????cmd?=?(Command)cmdList.get(i);
    13????????????cmd.execute();
    14????????}

    15????}
    ????
    16}

    3,需求:須要redo undo
    ? 解決:加入備忘錄模式,一個簡單的實現(xiàn)如下
    ?1public?class?ConcreteCommandOne?implements?Command{
    ?2????private?Receiver?receiver
    ?3????private?Receiver?lastReceiver;
    ?4????public?ConcreteCommandOne(Receiver?receiver){
    ?5????????this.receiver?=?receiver;
    ?6????}

    ?7????public?void?execute(){
    ?8????????record();
    ?9????????receiver.actionOne();
    10????}

    11????public?void?undo(){
    12????????//恢復狀態(tài)
    13????}

    14????public?void?redo(){
    15????????lastReceiver.actionOne();
    16????????//
    17????}

    18????public?record(){
    19????????//記錄狀態(tài)
    20????}

    21}

    4,需求:命令很多類似的地方
    ?? 解決:使用原型模式,利用clone
    ?? 這個就不寫例子了。
    四,命令模式的使用場合
    1,須要callback的時候,例如java awt/swing/swt中的Listening的消息方式
    2,須要對請求排隊執(zhí)行,命令的發(fā)送者和接受者有不同對的生命周期,就是命令執(zhí)行的時候,可能發(fā)出命令的
    Client已經(jīng)不存在了
    3,須要Redo Undo等函數(shù)
    4,須要log每條命令
    5,須要支持transaction,封裝一組數(shù)據(jù)命令的時候.
    五,最后再次總結(jié)一下命令模式的優(yōu)點和缺點:
    優(yōu)點:
    降低Client和命令接受者的耦合,是命令請求和命令執(zhí)行的對象分割
    便于修改和擴張
    便于聚合多個命令
    缺點:
    造成出現(xiàn)過多的具體命令類,太多文件。

    五,一個比較有意思的例子,來說明命令模式
    Client??????? :看電視的人
    Invoker???? :遙控器
    Command :電信號
    具體命令 :遙控器上的按鍵對應的不同的電信號
    Receiver??? :電視機
    最后說一句,并不是全部按照模式寫一定就好,應該根據(jù)你的需求來應用,或者全部應用,或者部分應用,或者根本不用。

    posted on 2007-02-26 09:38 liaojiyong 閱讀(364) 評論(0)  編輯  收藏 所屬分類: Java

    主站蜘蛛池模板: CAOPORM国产精品视频免费| 国产成人亚洲精品影院| 日本视频免费高清一本18| 亚洲AV成人精品日韩一区| 亚洲国产美女精品久久久久| 亚洲日韩aⅴ在线视频| 免费一级毛片在线播放不收费| a级毛片无码免费真人| 中文字幕免费视频一| 国产免费不卡视频| 国产亚洲综合视频| 亚洲国产超清无码专区| 亚洲国产精品久久久久婷婷软件 | 亚洲精品你懂的在线观看 | 亚洲精品又粗又大又爽A片| 亚洲日本国产精华液| 亚洲午夜久久久精品影院| 国产亚洲av片在线观看16女人| 国产成人亚洲综合无码| 亚洲国产精品专区在线观看| 四虎永久在线免费观看| 日韩免费在线观看| 日本免费的一级v一片| 天天干在线免费视频| 卡一卡二卡三在线入口免费| 日韩精品无码区免费专区| 在线观看特色大片免费视频| 免费毛片a在线观看67194| 免费观看无遮挡www的小视频| h片在线免费观看| 成人免费的性色视频| 国产成人无码免费看视频软件| 免费阿v网站在线观看g| 成年女人免费视频播放体验区| 日本精品人妻无码免费大全 | 中文字幕 亚洲 有码 在线| 亚洲宅男精品一区在线观看| 亚洲国产日韩精品| 噜噜综合亚洲AV中文无码| 美女视频黄频a免费大全视频| 四虎影视久久久免费观看|