目錄java
迭代器模式sql
爲何要用迭代器模式數據庫
迭代器模式應用實例編程
不知不覺更了12篇,從今天開始近乎天天全滿的課程開始了,更新速度也要受到影響。設計模式
迭代器,最先聽到這個概念的時候是在大一的時候還對java只知其一;不知其二就去搞Android的時候,接觸到的,在用到對於數據庫的操做的時候,咱們來得到數據的時候經過 rawQuery執行sql語句來得到數據集返回的就是一個遊標實例,Cursor,所以迭代器模式也被稱做是遊標模式,具體例子和其使用在後面實例部分介紹。數組
迭代器:提供一種方法來遍歷集合的同時,又不暴露該集合的底層數據存儲的實現。數據結構
咱們常見的集合有不少種類,其頂層數據存儲和組織方式的不一樣致使了咱們在對數據進行遍歷的時候存在一些差別,迭代器模式就是經過實現某種統一的方式來實現對不一樣的集合的遍歷,同時又不暴露出其底層的數據存儲和組織方式。ui
繼續咱們造機器的問題,在講適配器的時候提到了,咱們擁有不止一個商店,並且每一個商店裏所出售的貨物的種類也是不一樣的,懼於馬雲大大的「不作電子商務將無商可務」,決定不只僅是經過線下的這種銷售,在網上也進行出售,網上的店將做爲一個集合,集合線下店裏全部的產品,當有客戶下單,就有具備該上商品的網店進行發貨,那麼第一個要解決的問題就是我要知道這些商店裏都有什麼產品,因此須要他們給提供一個貨物的種類單,因爲不一樣的商店,其對商品種類管理使用的數據結構也是不相同的,有的是經過一個數組來存放,由於他們的店裏永遠只會賣固定種類的貨物,而後有一些店裏在不停的擴展規模,所以會經過一個可擴展的ArrayList來存放。(固然,現實中不會如此,爲了舉例方便)而後,如今各個商家給我數據了,並且不止這兩種,這個時候頭大了。this
開始,這樣來實現設計
public class Store{ //用來持有全部菜單條目 public ArrayList<MenuItem>list = new ArrayList<MenuItem>(); public Store(){ } //針對不一樣的商店建立不一樣的類型 public void getFirstStoreMachines(FirstStoreMenu menu){ MenuItem [] firstStoreMenu = menu.getMenuItems(); for(int i=0; i<firstStoreMenu.length; i++) list.add(firstStoreMenu[i]); } public void getSecondStoreMachines(SecondStoreMenu menu){ ArrayList<MenuItem> secondStoreMenu = menu.getMenuItems(); for(int i=0; i<secondStoreMenu.size(); i++) list.add(secondStoreMenu.get(i)); } //用來展現全部的商品種類 public void display(){ for(int i=0; i<list.size(); i++){ System.out.println(list.get(i).name); } } }
針對每個商店的數據集進行遍歷,來得到菜單條目,若是有一百個商店,那麼咱們的代碼量將變得很大,同時後期的維護也變得很困難了。
這個時候,又到了設計模式大顯身手的時候了。經過迭代器模式來給數組和容器包上一層,使得其內部結構對外徹底不可見,從而使得咱們無需針對每種數據結構單獨進行遍歷操做。代碼實例以下。
根據設計模式的基本原則針對接口編程,而不要針對具體類型,so
public interface Iterator{ boolean hasNext(); Object next(); }
看到這兩個方法,獲取sqlite數據庫中的數據的既視感。
而後以前咱們的商店菜單類是這樣實現的
public class FirstStoreMenu extends Menu{ MenuItem[] items; public MenuItem[] getFirstStoreMachines{ return items; } }
如今咱們要使用迭代器了,全部要返回一個迭代器了,返回什麼樣的迭代器,這個迭代器具體要怎麼實現呢?
public class FirstMenuIterator implements Iterator{ MenuItem[] items; int position=0; public FirstMenuIterator(MenuItem[] items){ this.items = items; } //向下移動 public Object next(){ MenuItem menuItem = items[position]; position++; return menuItem; } //判斷 public boolean hasNext(){ if(position>=items.length||items[position]==null){ return false; }else{ return true; } } } //經過判斷和移動的結合實現咱們須要的遍歷操做
有了針對咱們商店菜單的迭代器了,那麼接下來能夠這樣寫了
public class FirstStoreMenu extends Menu{ MenuItem[]items; public Iterator createIterator(){ return new FirstMenuIterator(items); } }
咱們總店中要如何應用這個迭代器呢?
public class Store{ //用來持有全部菜單條目 public ArrayList<MenuItem>list = new ArrayList<MenuItem>(); public Store(){ } public void addItem(Iterator iterator){ while(iterator.hasNext()) list.add(iterator.next()); } //用來展現全部的商品種類 public void display(){ for(int i=0; i<list.size(); i++){ System.out.println(list.get(i).name); } } }
經過這種方式,咱們不只使得代碼變得簡潔(Store內的代碼),同時也使得咱們的編程針對接口再進行編程。使得store類對各商店菜單類的耦合變低。這樣咱們經過addItem方法向Store實例注入依賴實例便可完成對於各個商店的商品的彙總。
上面提到了Android的數據庫sqlite得到數據的時候,固然對於數據集的操做迭代器是很經常使用的。
Android中叫它遊標,這個稱呼更好的反應出了特性,在數據集之上游走。具體代碼此處再也不貼出。
邊城大神,在文章中提到了一個橋接模式,對於這個模式,橋接模式其思想爲,將對象和行爲單獨封裝成類,對象的特徵和行爲鬆耦合,而後對象自身並不去實現行爲,經過對委託的形式調用行爲類,結構上比較像是策略模式的結構。
下篇更新生成器模式,結合Android中的AlertDialog.Builder來談下