設(shè)計(jì)模式-工具鏈模式和迭代器模式

設(shè)計(jì)模式-職責(zé)鏈模式和迭代器模式

1.職責(zé)鏈模式

  • 設(shè)計(jì)動(dòng)機(jī)

    客戶端發(fā)出一個(gè)請(qǐng)求威恼,職責(zé)鏈上的對(duì)象都可以處理這一請(qǐng)求癞蚕,而客戶端不需要知道是誰(shuí)具體處理這一請(qǐng)求妈拌,這樣就實(shí)現(xiàn)請(qǐng)求發(fā)送者和請(qǐng)求處理者的解耦迟杂,并且客戶端可以實(shí)現(xiàn)動(dòng)態(tài)的組合職責(zé)鏈。

  • 常規(guī)場(chǎng)景及存在問題

    請(qǐng)假manager類邏輯:
    if(請(qǐng)假天數(shù) <= 1) {
      handler(小組長(zhǎng))缀蹄;
    } else if(請(qǐng)假天數(shù) <= 3 && 請(qǐng)假天數(shù) > 1) {
      handler(分區(qū)經(jīng)理);
    } else if(請(qǐng)假天數(shù) <= 7 && 請(qǐng)假天數(shù) > 3) {
      handler(總經(jīng)理);
    } else {
      doOtherThing();
    }
    

    考慮兩種情況:

    • if判斷條件增多峭跳,假如100個(gè)—每次增加都需要增加manager類的判斷邏輯
    • 增加一種情況3<請(qǐng)假天數(shù)<5—修改manager類的判斷邏輯

    存在的問題:

    • 違反了設(shè)計(jì)模式中的開閉原則
    • 違反了設(shè)計(jì)模式中的單一職責(zé)原則
  • 職責(zé)鏈模式參考實(shí)例

    請(qǐng)求者類:

    public class Request {
          private String name;
          private int days;
          public Request(String name, int days) {
              this.name = name;
              this.days = days;
          }
          public String getName() {
              return name;
          }
          public int getDays() {
              return days;
          }
    }
    

    ?

    Handler抽象類:

    public abstract class Handler{
      protected Handler successor;
          public void setSuccessor(Handler successor) {
              this.successor = successor;
          }
      public abstract void handleRequest(Request request);
    }
    

    處理者類1:

    public class LeaveHandler1 extends Handler {
          public void handleRequest(Request request) {
              if (request.getDays() <= 1) {
                  System.out.println("小組長(zhǎng)審批,請(qǐng)假天數(shù)為:"+request.getDays());
              } else {
                  if (null != this.successor) {
                      this.successor.handleRequest(request);
                  }
              }
          }
    }
    

    處理者類2:

    public class LeaveHandler2 extends Handler {
          public void handleRequest(Request request) {
              if (request.getDays() <= 3 && request.getDays() > 1) {
                  System.out.println("分區(qū)經(jīng)理審批,請(qǐng)假天數(shù)為:"+request.getDays());
              } else {
                  if (null != this.successor) {
                      this.successor.handleRequest(request);
                  }
              }
          }
    }
    

    處理者類3:

    public class LeaveHandler3 extends Handler {
          public void handleRequest(Request request) {
              if (request.getDays() <= 7 && request.getDays() > 3) {
                  System.out.println("總經(jīng)理審批,請(qǐng)假天數(shù)為:"+request.getDays());
              } else {
                  if (null != this.successor) {
                      this.successor.handleRequest(request);
                  }
              }
          }
    }
    

    客戶端主函數(shù):

    public class Main{
          public static void main(String args[]) {
              Handler groupLeader = new LeaveHandler1();
              Handler partManager = new LeaveHandler2();
              Handler manager = new LeaveHandler3();
              groupLeader.setSuccessor(partManager);
              partManager.setSuccessor(manager);
              Request req1 = new Request("李四",4);
              groupLeader.handleRequest(req1);
          }
    }
    

    職責(zé)鏈模式好處:

    • 請(qǐng)求者和處理者都沒有對(duì)方明確的信息,并且鏈中的對(duì)象不需要知道所有處理者的引用缺前,只需要知道后繼者的引用就行了蛀醉。降低了模塊和對(duì)象之間的耦合度
    • 可以在鏈中隨時(shí)增加或修改一個(gè)請(qǐng)求的結(jié)構(gòu),動(dòng)態(tài)組合職責(zé)衅码, 增加了靈活性

    可能存在的問題:

    • 請(qǐng)求在末端都得不到處理
    • 避免鏈出現(xiàn)環(huán)拯刁,應(yīng)該為鏈增加默認(rèn)的處理

2. 迭代器模式

  • 設(shè)計(jì)動(dòng)機(jī)

    提供一種方法順序訪問聚合對(duì)象中的各個(gè)元素,并且不暴露該對(duì)象中的內(nèi)部表示逝段。迭代器的作用就是把容器中的對(duì)象一個(gè)一個(gè)遍歷出來(lái)垛玻。

  • 迭代器核心

    集合抽象類(Aggregate):定義集合接口

    具體集合類(ConcreteAggregate): 繼承Aggregate接口,實(shí)現(xiàn)集合

    迭代抽象類(Iterator): 定義迭代器接口-開始對(duì)象, 得到下一個(gè)對(duì)象, 當(dāng)前對(duì)象, 判斷是否到結(jié)尾

    具體迭代器類(ConcreteIterator): 繼承Iterator奶躯,實(shí)現(xiàn)迭代器接口

  • 迭代器模式參考實(shí)例

    集合抽象類:

    interface  Aggregate {
          Iterator createIterator();
    }
    

    集合具體類:

    public class ConcreteAggregate implements Aggregate {
          private List<Object> list;
          public ConcreteAggregate(List<Object> list) {
              this.list = list;
          }
          @Override
          public Iterator createIterator() {
              return new ConcreteIrerator(list);
          }
    }
    

    迭代抽象類:

    interface Iterator {
          Object first();
          Object next();
          boolean isLast();
          Object current();
    }
    

    具體迭代器類:

    class ConcreteIterator implements Iterator {
          private int cursor;
          private List<Object> list;
          public ConcreteIterator(List<Object> list) {
          this.list = list;
          }
          @Override
          public Object first() {
          return list.get(0);
          }
          @Override
          public Object next() {
          Object ret = null
          if (!isLast()) {
            ret = list.get(cursor);
          }
          cursor++;
          return ret;
          }
          @Override
          public boolean isLast() {
          return cursor >= list.size() ? true:false;
          }
          @Override
          public Object current() {
          return list.get(cursor);
          }
    }
    

    客戶端代碼:

    public class client {
          public static void main(String[] args) {
              List<Object> list = new ArrayList<Object>();
              list.add("zhangsan");
              list.add("wangwu");
              list.add("lisi");
              Aggregate aggregate = new ConcreteAggregate(list);
              Iterator iterator = aggregate.createIterator();
              while (!iterator.isLast()) {
              System.out.println(iterator.next());
              }
          }
    }
    

    迭代器模式好處:

    • 客戶端只需要得到迭代器就可以遍歷帚桩,不用關(guān)心遍歷算法,封裝性好
    • 可以方便的提供多種遍歷方式
    • 不需要暴露容器集合的內(nèi)部數(shù)據(jù)結(jié)構(gòu)嘹黔,又可以透明的訪問集合內(nèi)部的數(shù)據(jù)

參考:《大話設(shè)計(jì)模式》
?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末账嚎,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子儡蔓,更是在濱河造成了極大的恐慌醉锄,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浙值,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡檩小,警方通過查閱死者的電腦和手機(jī)开呐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人筐付,你說(shuō)我怎么就攤上這事卵惦。” “怎么了瓦戚?”我有些...
    開封第一講書人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵沮尿,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我较解,道長(zhǎng)畜疾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任印衔,我火速辦了婚禮啡捶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘奸焙。我一直安慰自己瞎暑,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開白布与帆。 她就那樣靜靜地躺著了赌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪玄糟。 梳的紋絲不亂的頭發(fā)上勿她,一...
    開封第一講書人閱讀 51,274評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音茶凳,去河邊找鬼嫂拴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛贮喧,可吹牛的內(nèi)容都是我干的筒狠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼箱沦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼辩恼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起谓形,我...
    開封第一講書人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤灶伊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后寒跳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體聘萨,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年童太,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了米辐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胸完。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖翘贮,靈堂內(nèi)的尸體忽然破棺而出赊窥,到底是詐尸還是另有隱情,我是刑警寧澤狸页,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布锨能,位于F島的核電站,受9級(jí)特大地震影響芍耘,放射性物質(zhì)發(fā)生泄漏址遇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一齿穗、第九天 我趴在偏房一處隱蔽的房頂上張望傲隶。 院中可真熱鬧,春花似錦窃页、人聲如沸跺株。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)乒省。三九已至,卻和暖如春畦木,著一層夾襖步出監(jiān)牢的瞬間袖扛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工十籍, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蛆封,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓勾栗,卻偏偏與公主長(zhǎng)得像惨篱,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子围俘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容