<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【設(shè)計(jì)模式】命令模式助力快速添加新命令而不影響現(xiàn)有代碼

      概述

      日常生活中,我們出去吃飯都會(huì)遇到下面的場景。

      定義:

      將一個(gè)請求封裝為一個(gè)對象,使發(fā)出請求的責(zé)任和執(zhí)行請求的責(zé)任分割開。這樣兩者之間通過命令對象進(jìn)行溝通,這樣方便將命令對象進(jìn)行存儲(chǔ)、傳遞、調(diào)用、增加與管理。

      結(jié)構(gòu)

      命令模式包含以下主要角色:

      • 抽象命令類(Command)角色: 定義命令的接口,聲明執(zhí)行的方法。

      • 具體命令(Concrete Command)角色:具體的命令,實(shí)現(xiàn)命令接口;通常會(huì)持有接收者,并調(diào)用接收者的功能來完成命令要執(zhí)行的操作。

      • 實(shí)現(xiàn)者/接收者(Receiver)角色: 接收者,真正執(zhí)行命令的對象。任何類都可能成為一個(gè)接收者,只要它能夠?qū)崿F(xiàn)命令要求實(shí)現(xiàn)的相應(yīng)功能。

      • 調(diào)用者/請求者(Invoker)角色: 要求命令對象執(zhí)行請求,通常會(huì)持有命令對象,可以持有很多的命令對象。這個(gè)是客戶端真正觸發(fā)命令并要求命令執(zhí)行相應(yīng)操作的地方,也就是說相當(dāng)于使用命令對象的入口。

      案例實(shí)現(xiàn)

      將上面的案例用代碼實(shí)現(xiàn),那我們就需要分析命令模式的角色在該案例中由誰來充當(dāng)。

      服務(wù)員: 就是調(diào)用者角色,由她來發(fā)起命令。

      資深大廚: 就是接收者角色,真正命令執(zhí)行的對象。

      訂單: 命令中包含訂單。

      類圖如下:

      代碼如下:

      public interface Command {
          void execute();//只需要定義一個(gè)統(tǒng)一的執(zhí)行方法
      }
      
      public class OrderCommand implements Command {
      
          //持有接受者對象
          private SeniorChef receiver;
          private Order order;
      
          public OrderCommand(SeniorChef receiver, Order order){
              this.receiver = receiver;
              this.order = order;
          }
      
          public void execute()  {
              System.out.println(order.getDiningTable() + "桌的訂單:");
              Set<String> keys = order.getFoodDic().keySet();
              for (String key : keys) {
                  receiver.makeFood(order.getFoodDic().get(key),key);
              }
      
              try {
                  Thread.sleep(100);//停頓一下 模擬做飯的過程
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
      
      
              System.out.println(order.getDiningTable() + "桌的飯弄好了");
          }
      }
      
      public class Order {
          // 餐桌號(hào)碼
          private int diningTable;
      
          // 用來存儲(chǔ)餐名并記錄份數(shù)
          private Map<String, Integer> foodDic = new HashMap<String, Integer>();
      
          public int getDiningTable() {
              return diningTable;
          }
      
          public void setDiningTable(int diningTable) {
              this.diningTable = diningTable;
          }
      
          public Map<String, Integer> getFoodDic() {
              return foodDic;
          }
      
          public void setFoodDic(String name, int num) {
              foodDic.put(name,num);
          }
      }
      
      // 資深大廚類 是命令的Receiver
      public class SeniorChef {
      
          public void makeFood(int num,String foodName) {
              System.out.println(num + "份" + foodName);
          }
      }
      
      public class Waitor {
      
          private ArrayList<Command> commands;//可以持有很多的命令對象
      
          public Waitor() {
              commands = new ArrayList();
          }
          
          public void setCommand(Command cmd){
              commands.add(cmd);
          }
      
          // 發(fā)出命令 喊 訂單來了,廚師開始執(zhí)行
          public void orderUp() {
              System.out.println("美女服務(wù)員:叮咚,大廚,新訂單來了.......");
              for (int i = 0; i < commands.size(); i++) {
                  Command cmd = commands.get(i);
                  if (cmd != null) {
                      cmd.execute();
                  }
              }
          }
      }
      
      public class Client {
          public static void main(String[] args) {
              //創(chuàng)建2個(gè)order
              Order order1 = new Order();
              order1.setDiningTable(1);
              order1.getFoodDic().put("西紅柿雞蛋面",1);
              order1.getFoodDic().put("小杯可樂",2);
      
              Order order2 = new Order();
              order2.setDiningTable(3);
              order2.getFoodDic().put("尖椒肉絲蓋飯",1);
              order2.getFoodDic().put("小杯雪碧",1);
      
              //創(chuàng)建接收者
              SeniorChef receiver=new SeniorChef();
              //將訂單和接收者封裝成命令對象
              OrderCommand cmd1 = new OrderCommand(receiver, order1);
              OrderCommand cmd2 = new OrderCommand(receiver, order2);
              //創(chuàng)建調(diào)用者 waitor
              Waitor invoker = new Waitor();
              invoker.setCommand(cmd1);
              invoker.setCommand(cmd2);
      
              //將訂單帶到柜臺(tái) 并向廚師喊 訂單來了
              invoker.orderUp();
          }
      }
      

      優(yōu)缺點(diǎn)

      優(yōu)點(diǎn):

      • 降低系統(tǒng)的耦合度。命令模式能將調(diào)用操作的對象與實(shí)現(xiàn)該操作的對象解耦。

      • 增加或刪除命令非常方便。采用命令模式增加與刪除命令不會(huì)影響其他類,它滿足“開閉原則”,對擴(kuò)展比較靈活。

      • 可以實(shí)現(xiàn)宏命令。命令模式可以與組合模式結(jié)合,將多個(gè)命令裝配成一個(gè)組合命令,即宏命令。

      • 方便實(shí)現(xiàn) Undo 和 Redo 操作。命令模式可以與后面介紹的備忘錄模式結(jié)合,實(shí)現(xiàn)命令的撤銷與恢復(fù)。

      缺點(diǎn):

      • 使用命令模式可能會(huì)導(dǎo)致某些系統(tǒng)有過多的具體命令類。不過不會(huì)導(dǎo)致類爆炸

      • 系統(tǒng)結(jié)構(gòu)更加復(fù)雜。

      使用場景

      • 系統(tǒng)需要將請求調(diào)用者和請求接收者解耦,使得調(diào)用者和接收者不直接交互。

      • 系統(tǒng)需要在不同的時(shí)間指定請求、將請求排隊(duì)和執(zhí)行請求。

      • 系統(tǒng)需要支持命令的撤銷(Undo)操作和恢復(fù)(Redo)操作。

      源碼解析 - Runable

      Runable是一個(gè)典型命令模式,Runnable擔(dān)當(dāng)命令的角色,Thread充當(dāng)?shù)氖钦{(diào)用者,start方法就是其執(zhí)行方法

      //命令接口(抽象命令角色)
      public interface Runnable {
          public abstract void run();
      }
      
      //調(diào)用者
      public class Thread implements Runnable {
          private Runnable target;
          
          public synchronized void start() {
              if (threadStatus != 0)
                  throw new IllegalThreadStateException();
      
              group.add(this);
      
              boolean started = false;
              try {
                  start0();
                  started = true;
              } finally {
                  try {
                      if (!started) {
                          group.threadStartFailed(this);
                      }
                  } catch (Throwable ignore) {
                  }
              }
          }
          
          private native void start0();
      }
      

      會(huì)調(diào)用一個(gè)native方法start0(),調(diào)用系統(tǒng)方法,開啟一個(gè)線程。而接收者是對程序員開放的,可以自己定義接收者。

      /**
       * jdk Runnable 命令模式
       *        TurnOffThread : 屬于具體
       */
      public class TurnOffThread implements Runnable{
           private Receiver receiver;
          
           public TurnOffThread(Receiver receiver) {
               this.receiver = receiver;
           }
           public void run() {
               receiver.turnOFF();
           }
      }
      
      /**
       * 測試類
       */
      public class Demo {
           public static void main(String[] args) {
               Receiver receiver = new Receiver();
               TurnOffThread turnOffThread = new TurnOffThread(receiver);
               Thread thread = new Thread(turnOffThread);
               thread.start();
           }
      }
      

      往期推薦

      posted @ 2025-03-12 11:38  程序員Seven  閱讀(70)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 亚洲国产欧美在线观看片| 亚洲人成电影网站 久久影视 | 日韩av日韩av在线| 亚洲精品国模一区二区| 中文精品无码中文字幕无码专区| 国产午夜福利视频在线| 亚洲第一区二区三区av| 精品国产国语对白主播野战| 浪卡子县| 亚洲性一交一乱一伦视频| 日本成人午夜一区二区三区| 一区二区三区午夜无码视频| 狠狠亚洲色一日本高清色| 国产婷婷精品av在线| 52熟女露脸国语对白视频| 午夜精品极品粉嫩国产尤物| 亚洲一区二区三区av链接| 五月天天天综合精品无码| 3d动漫精品一区二区三区| 国产午夜福利视频一区二区| 国产亚洲人成网站在线观看| 亚洲一区二区精品偷拍| 青青国产揄拍视频| 欧美成人aaa片一区国产精品| 夜夜影院未满十八勿进| 国产乱子影视频上线免费观看| 蜜臀av一区二区精品字幕| 国产成人亚洲精品狼色在线 | 小嫩批日出水无码视频免费| 丁香婷婷激情俺也去俺来也| 极品少妇无套内射视频| av无码小缝喷白浆在线观看| 亚洲和欧洲一码二码三码| 金山区| 一区二区三区不卡国产| 日韩成人无码影院| 亚洲精品一区二区三区四区乱码| 精品国产亚洲午夜精品a| 国产69精品久久久久人妻刘玥| 色综合久久综合久鬼色88| 最新中文字幕国产精品|