“數據結構”模式

常常有一些組件在內部具有特定的數據結構,如果讓客戶程序依賴這些特定的數據結構,將極大地破壞組件的復用。這時候,將這些特定數據結構封裝在內部,在外部提供統一的接口,來實現與特定數據結構無關的訪問,是一種行之有效的解決方案。

典型模式

  • Composite
  • Iterator
  • Chain of Resposibility

1.Composite模式(舉例android:View)


動機

  • 在軟件某些情況下,客戶代碼過多地依賴于對象容器復雜的內部實現結構,對象容器內部實現結構(而非抽象接口)的變化將引起客戶代碼的頻繁變化,帶來了代碼的維護性、擴展性等弊端。

  • 如何將“客戶代碼與復雜的對象容器結構”解耦?讓對象容器自己來實現自身的復雜結構,從而使得使得客戶代碼就像處理簡單對象一樣來處理復雜的對象容器?

模式定義

  • 將對象組合成樹形結構以表示“部分整體”的層次結構。組合模式使得用戶對單個對象和使用具有一致性(穩定)。

結構

類圖

涉及角色

  • 1.Component 是組合中的對象聲明接口,在適當的情況下,實現所有類共有接口的默認行為。聲明一個接口用于訪問和管理Component子部件。
  • 2.Leaf 在組合中表示葉子結點對象,葉子結點沒有子結點。
  • 3.Composite 定義有枝節點行為,用來存儲子部件,在Component接口中實現與子部件有關操作,如增加(add)和刪除(remove)等

要點總結

  • Composite模式采用樹形結構來實現普遍存在的對象容器,從而將“一對多”的關系轉化為“一對一”的關系,使得客戶代碼可以一致地(復用)處理對象和對象容器,無需關心處理的是單個的對象,還是組合的對象容器。
  • 將“客戶代碼與復雜的對象容器結構”解耦是Composite的核心思想,解耦之后,客戶代碼將與純粹的抽象接口——而非對象容器的內部實現結構——發生依賴,從而更能“應對變化”。
  • Composite模式在具體實現中,可以讓父對象中的子對象反向追溯;如果父對性愛那個有頻繁的遍歷需求,可使用緩存技巧來改善效率。

2.Iterator迭代器


動機

  • 在軟件構建過程中,集合對象內部結構常常變化各異。但對于這些集合對象,我們希望在不暴露其內部結構的同時,可以讓外部客戶代碼透明地訪問其中包含的元素;同時這種“透明遍歷”也為“同一種算法在多種集合對象上進行操作”提供了可能。
  • 使用面向對象技術將這種遍歷機制抽象為“迭代器對象”為“應對變化中的集合對象”
    提供了一種優雅的方式。

模式定義

  • 提供一種方法順序訪問一個聚合對象中的各個元素,而又不暴露(穩定)該對象的內部表示。

結構

類圖

結構組成

  • 抽象迭代器(Iterator): 定義遍歷元素所需要的方法,一般來說會有這么三個方法:取得第一個元素的方法first(),取得下一個元素的方法next(),判斷是否遍歷結束的方法isDone()(或者叫hasNext()),移出當前對象的方法remove(),
  • 具體迭代器(ConcreteIterator): 就是抽象容器的具體實現類,比如List接口的有序列表實現ArrayList,List接口的鏈表實現LinkList,Set接口的哈希列表的實現HashSet等。
  • 抽象聚合類(Aggregate): 一般是一個接口,提供一個iterator()方法,例如java中的Collection接口,List接口,Set接口等。
  • 具體聚合類(ConcreteAggregate): 聚合實現創建相應迭代器的接口,該操作返回ConcreteIterator的一個適當的實例。

代碼實現

  interface Iterator {  
      public Object next();  
      public boolean hasNext();  
  }  
  class ConcreteIterator implements Iterator{  
      private List list = new ArrayList();  
      private int cursor =0;  
      public ConcreteIterator(List list){  
          this.list = list;  
      }  
      public boolean hasNext() {  
          if(cursor==list.size()){  
              return false;  
          }  
          return true;  
      }  
      public Object next() {  
          Object obj = null;  
          if(this.hasNext()){  
              obj = this.list.get(cursor++);  
          }  
          return obj;  
      }  
  }  
  interface Aggregate {  
      public void add(Object obj);  
      public void remove(Object obj);  
      public Iterator iterator();  
  }  
  class ConcreteAggregate implements Aggregate {  
      private List list = new ArrayList();  
      public void add(Object obj) {  
          list.add(obj);  
      }  
    
      public Iterator iterator() {  
          return new ConcreteIterator(list);  
      }  
    
      public void remove(Object obj) {  
          list.remove(obj);  
      }  
  }  
  public class Client {  
      public static void main(String[] args){  
          Aggregate ag = new ConcreteAggregate();  
          ag.add("小明");  
          ag.add("小紅");  
          ag.add("小剛");  
          Iterator it = ag.iterator();  
          while(it.hasNext()){  
              String str = (String)it.next();  
              System.out.println(str);  
          }  
      }  
  }  

要點總結

  • 迭代抽象:訪問一個聚合對象的內容而無需暴露它的內部表示。
  • 迭代多態:為遍歷不同的集合結構提供一個統一的接口,從而支持同樣的算法在不同的集合結構上進行操作。
  • 迭代器的健壯性考慮:遍歷的同時更改迭代器所在的集合結構(add、remove)會導致問題(拋出異常)。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,443評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,530評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,407評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,981評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,759評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,204評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,263評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,415評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,955評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,650評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,892評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,675評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,967評論 2 374

推薦閱讀更多精彩內容