男女做暖暖暖網(wǎng)站2345軟件為什么沒人管
目錄
場景
解決方案
解決思路
代碼示例
代碼改造
Java實(shí)現(xiàn)迭代器
迭代器模式的優(yōu)點(diǎn)?
思考?
何時(shí)選用
場景
大公司收購了一個(gè)小公司,大公司的工資系統(tǒng)采用List來記錄工資列表,而小公司是采用數(shù)組,老板希望通過決策輔助系統(tǒng)來統(tǒng)一查看工資數(shù)據(jù)不想看到兩份不同的工資表。
解析:如何能夠以一個(gè)統(tǒng)一的方式 來訪問 內(nèi)部實(shí)現(xiàn)不同的 聚合對象
解決方案
迭代器模式
定義:
所謂聚合就是指一組對象的組合結(jié)構(gòu):比如?Java中的集合、數(shù)組等
解決思路
要有一個(gè)統(tǒng)一的方式來訪問,那就要定義這個(gè)統(tǒng)一的訪問方式,那么按照統(tǒng)一的訪問方式定義出來的接口就應(yīng)該是Iterator接口。(定義訪問和遍歷元素的接口)
迭代器迭代的是具體的聚合對象,不同的聚合對象應(yīng)該有不同的迭代器,所以應(yīng)該抽象出來一個(gè)公共的父類,讓它提供 操作聚合對象的 公共接口。也是就Aggregate對象(聚合對象)
如何創(chuàng)建?由于迭代器與聚合對象緊密相關(guān),因此讓具體的聚合對象來負(fù)責(zé)創(chuàng)建相應(yīng)的迭代器對象
代碼示例
工資實(shí)體
package day13迭代器模式.entity;/*** 工資實(shí)體*/
public class PayModel {/*** 支付工資的人員*/private String userName;/*** 支付的工資數(shù)額*/private double pay;public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public double getPay() {return pay;}public void setPay(double pay) {this.pay = pay;}@Overridepublic String toString() {return "PayModel{" +"userName='" + userName + '\'' +", pay=" + pay +'}';}
}
大公司原有的工資管理對象 使用List
package day13迭代器模式;import day13迭代器模式.entity.PayModel;import java.util.ArrayList;
import java.util.List;/*** 大公司原有的工資管理對象*/
public class PayDa {/*** 聚合對象*/private List list = new ArrayList();/*** 獲取工資列表* @return 工資列表*/public List getPayList(){return list;}/*** 計(jì)算工資*/public void calcPay(){// 計(jì)算工資并把工資數(shù)據(jù)填充到工資列表中// 為了測試,輸入些數(shù)據(jù)進(jìn)去PayModel payModel = new PayModel();payModel.setPay(3800);payModel.setUserName("張三");PayModel payModel1 = new PayModel();payModel1.setPay(5800);payModel1.setUserName("李四");list.add(payModel);list.add(payModel1);}
}
小公司原有的工資管理對象 使用數(shù)組
package day13迭代器模式;import day13迭代器模式.entity.PayModel;import java.util.ArrayList;
import java.util.List;/*** 小公司原有的工資管理對象*/
public class PayXiao {/*** 用數(shù)組管理*/private PayModel[] pms = null;/*** 獲取工資列表* @return 工資列表*/public PayModel[] getPays(){return pms;}/*** 計(jì)算工資*/public void calcPay(){// 計(jì)算工資并把工資數(shù)據(jù)填充到工資列表中// 為了測試,輸入些數(shù)據(jù)進(jìn)去PayModel payModel = new PayModel();payModel.setPay(3800);payModel.setUserName("張三");PayModel payModel1 = new PayModel();payModel1.setPay(5800);payModel1.setUserName("李四");pms = new PayModel[2];pms[0] = payModel;pms[1] = payModel1;}
}
Client
package day13迭代器模式;import day13迭代器模式.entity.PayModel;import java.util.Collection;
import java.util.Iterator;
import java.util.List;public class Client {public static void main(String[] args) {// 訪問集團(tuán)的工資列表PayDa payDa = new PayDa();// 先計(jì)算再獲取payDa.calcPay();List payList = payDa.getPayList();Iterator it = payList.iterator();System.out.println("大公司工資列表: ");while (it.hasNext()){PayModel next = (PayModel)it.next();System.out.println(next);}// 訪問小公司的工資列表PayXiao payXiao = new PayXiao();payXiao.calcPay();PayModel[] pays = payXiao.getPays();System.out.println("小公司工資列表: ");for (int i = 0; i < pays.length; i++) {System.out.println(pays[i]);}}
}
發(fā)現(xiàn)他們的訪問方式是完全不一樣的(一個(gè)是list,一個(gè)是對象數(shù)組)。
要使用迭代器來整合上面兩個(gè)聚合對象,那就需要先定義出抽象的聚合對象和迭代器接口來,再提供相應(yīng)的實(shí)現(xiàn)
代碼改造
Iterator
package day13迭代器模式;public interface Iterator {/*** 移動到聚合對象的第一個(gè)位置*/public void first();/*** 移動到聚合對象的下一個(gè)位置*/public void next();/*** 判斷是否移動到聚合對象的最后一個(gè)位置* @return true表示已經(jīng)移動到聚合對象的最后一個(gè)位置* false表示沒有移動到聚合對象的最后一個(gè)位置*/public boolean isDone();/*** 獲取迭代的當(dāng)前元素* @return 迭代的當(dāng)前元素*/public Object currentItem();
}
?定義好統(tǒng)一接口后,就得分別實(shí)現(xiàn),一個(gè)是List實(shí)現(xiàn),一個(gè)是數(shù)組實(shí)現(xiàn)
數(shù)組實(shí)現(xiàn)
package day13迭代器模式.Iterator;import day13迭代器模式.PayXiao;/*** 用來實(shí)現(xiàn)訪問數(shù)組的迭代接口*/
public class ArrayIteratorImpl implements Iterator{/*** 用來存放被迭代的聚合對象*/private PayXiao payXiao = null;/*** 用來記錄當(dāng)前迭代到的位置索引* -1表示剛開始的時(shí)候,迭代器指向聚合對象第一個(gè)對象之前*/private int index = -1;/*** 構(gòu)造函數(shù),傳入聚合對象*/public ArrayIteratorImpl(PayXiao payXiao){this.payXiao = payXiao;}@Overridepublic void first() {index = 0;}@Overridepublic void next() {if (index < this.payXiao.size()){index = index + 1;}}@Overridepublic boolean isDone() {if (index == this.payXiao.size()){return true;}return false;}@Overridepublic Object currentItem() {return this.payXiao.get(index);}
}
集合實(shí)現(xiàn)
package day13迭代器模式.Iterator;import day13迭代器模式.PayDa;public class CollectionIteratorImpl implements Iterator{/*** 用來存放被迭代的聚合對象*/private PayDa payDa = null;/*** 用來記錄當(dāng)前迭代到的位置索引* -1表示剛開始的時(shí)候,迭代器指向聚合對象第一個(gè)對象之前*/private int index = -1;/*** 構(gòu)造函數(shù),傳入聚合對象*/public CollectionIteratorImpl(PayDa payDa){this.payDa = payDa;}@Overridepublic void first() {index = 0;}@Overridepublic void next() {if (index < this.payDa.size()){index = index + 1;}}@Overridepublic boolean isDone() {if (index == this.payDa.size()){return true;}return false;}@Overridepublic Object currentItem() {return this.payDa.get(index);}
}
迭代器迭代的是具體的聚合對象,不同的聚合對象應(yīng)該有不同的迭代器,所以應(yīng)該抽象出來一個(gè)公共的父類,讓它提供 操作聚合對象的 公共接口。
也是就Aggregate對象(聚合對象)
package day13迭代器模式;import day13迭代器模式.Iterator.Iterator;/*** 迭代器迭代的是具體的聚合對象,不同的聚合對象應(yīng)該有不同的迭代器,* 所以應(yīng)該抽象出來一個(gè)公共的父類,讓它提供 操作聚合對象的 公共接口。* 也是就Aggregate對象(聚合對象)*/
public abstract class Aggregate {/*** 工廠方法,創(chuàng)建對應(yīng)迭代器對象的接口*/public abstract Iterator createIterator();
}
讓PayDa和PayXiao,這兩個(gè)原有的工資管理對象繼承這個(gè)Aggregate
PayDa
package day13迭代器模式;import day13迭代器模式.Iterator.CollectionIteratorImpl;
import day13迭代器模式.Iterator.Iterator;
import day13迭代器模式.entity.PayModel;import java.util.ArrayList;
import java.util.List;/*** 大公司原有的工資管理對象*/
public class PayDa extends Aggregate{/*** 聚合對象*/private List list = new ArrayList();/*** 獲取工資列表* @return 工資列表*/public List getPayList(){return list;}/*** 計(jì)算工資*/public void calcPay(){// 計(jì)算工資并把工資數(shù)據(jù)填充到工資列表中// 為了測試,輸入些數(shù)據(jù)進(jìn)去PayModel payModel = new PayModel();payModel.setPay(3800);payModel.setUserName("張三");PayModel payModel1 = new PayModel();payModel1.setPay(5800);payModel1.setUserName("李四");list.add(payModel);list.add(payModel1);}@Overridepublic Iterator createIterator() {return new CollectionIteratorImpl(this);}public Object get(int index){Object obj = null;if (index < this.list.size()){obj = this.list.get(index);}return obj;}public int size(){return this.list.size();}
}
PayXiao
package day13迭代器模式;import day13迭代器模式.Iterator.ArrayIteratorImpl;
import day13迭代器模式.Iterator.Iterator;
import day13迭代器模式.entity.PayModel;import java.util.ArrayList;
import java.util.List;/*** 小公司原有的工資管理對象*/
public class PayXiao extends Aggregate{/*** 用數(shù)組管理*/private PayModel[] pms = null;/*** 獲取工資列表* @return 工資列表*/public PayModel[] getPays(){return pms;}/*** 計(jì)算工資*/public void calcPay(){// 計(jì)算工資并把工資數(shù)據(jù)填充到工資列表中// 為了測試,輸入些數(shù)據(jù)進(jìn)去PayModel payModel = new PayModel();payModel.setPay(3800);payModel.setUserName("張三");PayModel payModel1 = new PayModel();payModel1.setPay(5800);payModel1.setUserName("李四");pms = new PayModel[2];pms[0] = payModel;pms[1] = payModel1;}@Overridepublic Iterator createIterator() {return new ArrayIteratorImpl(this);}public Object get(int index){Object obj = null;if (index < pms.length){obj = pms[index];}return obj;}public int size(){return this.pms.length;}
}
Client
package day13迭代器模式;import day13迭代器模式.entity.PayModel;import java.util.Collection;
import java.util.Iterator;
import java.util.List;public class Client {public static void main(String[] args) {// 訪問集團(tuán)的工資列表PayDa payDa = new PayDa();// 先計(jì)算再獲取payDa.calcPay();
// List payList = payDa.getPayList();
// Iterator it = payList.iterator();System.out.println("大公司工資列表: ");
// while (it.hasNext()){
// PayModel next = (PayModel)it.next();
// System.out.println(next);
// }test(payDa.createIterator());// 訪問小公司的工資列表PayXiao payXiao = new PayXiao();payXiao.calcPay();
// PayModel[] pays = payXiao.getPays();System.out.println("小公司工資列表: ");test(payXiao.createIterator());}private static void test(day13迭代器模式.Iterator.Iterator it){// 循環(huán)輸出聚合對象中的值// 首先設(shè)置迭代器到第一個(gè)元素it.first();while (!it.isDone()){// 取出當(dāng)前的元素來Object o = it.currentItem();System.out.println("當(dāng)前元素: " + o);it.next();}}
}
迭代器模式的關(guān)鍵思想就是把聚合對象的遍歷和訪問從聚合對象中分離出來,放入單獨(dú)的迭代器中。
Java實(shí)現(xiàn)迭代器
PayModel類(工資實(shí)體)
package day13迭代器Java實(shí)現(xiàn).entity;/*** 工資實(shí)體*/
public class PayModel {/*** 支付工資的人員*/private String userName;/*** 支付的工資數(shù)額*/private double pay;public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public double getPay() {return pay;}public void setPay(double pay) {this.pay = pay;}@Overridepublic String toString() {return "PayModel{" +"userName='" + userName + '\'' +", pay=" + pay +'}';}
}
創(chuàng)建Aggregate,這里使用java.util.Iterator
package day13迭代器Java實(shí)現(xiàn);import java.util.Iterator;/*** 迭代器迭代的是具體的聚合對象,不同的聚合對象應(yīng)該有不同的迭代器,* 所以應(yīng)該抽象出來一個(gè)公共的父類,讓它提供 操作聚合對象的 公共接口。* 也是就Aggregate對象(聚合對象)*/
public abstract class Aggregate {/*** 工廠方法,創(chuàng)建對應(yīng)迭代器對象的接口*/public abstract Iterator createIterator();
}
PayDa繼承該抽象類
package day13迭代器Java實(shí)現(xiàn);import day13迭代器Java實(shí)現(xiàn).entity.PayModel;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;/*** 大公司原有的工資管理對象*/
public class PayDa extends Aggregate {/*** 聚合對象*/private List<PayModel> list = new ArrayList<PayModel>();/*** 獲取工資列表* @return 工資列表*/public List<PayModel> getPayList(){return list;}/*** 計(jì)算工資*/public void calcPay(){// 計(jì)算工資并把工資數(shù)據(jù)填充到工資列表中// 為了測試,輸入些數(shù)據(jù)進(jìn)去PayModel payModel = new PayModel();payModel.setPay(3800);payModel.setUserName("張三");PayModel payModel1 = new PayModel();payModel1.setPay(5800);payModel1.setUserName("李四");list.add(payModel);list.add(payModel1);}@Overridepublic Iterator createIterator() {return list.iterator();}}
PayXiao繼承該抽象類
package day13迭代器Java實(shí)現(xiàn);import day13迭代器Java實(shí)現(xiàn).Iterator.ArrayIteratorImpl;
import day13迭代器Java實(shí)現(xiàn).entity.PayModel;import java.util.Iterator;/*** 小公司原有的工資管理對象*/
public class PayXiao extends Aggregate {/*** 用數(shù)組管理*/private PayModel[] pms = null;/*** 獲取工資列表* @return 工資列表*/public PayModel[] getPays(){return pms;}/*** 計(jì)算工資*/public void calcPay(){// 計(jì)算工資并把工資數(shù)據(jù)填充到工資列表中// 為了測試,輸入些數(shù)據(jù)進(jìn)去PayModel payModel = new PayModel();payModel.setPay(3800);payModel.setUserName("張三");PayModel payModel1 = new PayModel();payModel1.setPay(5800);payModel1.setUserName("李四");pms = new PayModel[2];pms[0] = payModel;pms[1] = payModel1;}@Overridepublic Iterator createIterator() {return new ArrayIteratorImpl(this);}public Object get(int index){Object obj = null;if (index < pms.length){obj = pms[index];}return obj;}public int size(){return this.pms.length;}
}
將小公司的融入大公司,就讓小公司來實(shí)現(xiàn)這個(gè)迭代器,讓它進(jìn)行統(tǒng)一
ArrayIteratorImpl
package day13迭代器Java實(shí)現(xiàn).Iterator;import day13迭代器Java實(shí)現(xiàn).PayXiao;import java.util.Iterator;/*** 用來實(shí)現(xiàn)訪問數(shù)組的迭代接口*/
public class ArrayIteratorImpl implements Iterator {/*** 用來存放被迭代的聚合對象*/private PayXiao payXiao = null;/*** 用來記錄當(dāng)前迭代到的位置索引* -1表示剛開始的時(shí)候,迭代器指向聚合對象第一個(gè)對象之前*/private int index = 0;/*** 構(gòu)造函數(shù),傳入聚合對象*/public ArrayIteratorImpl(PayXiao payXiao){this.payXiao = payXiao;}@Overridepublic void remove() {Iterator.super.remove();}/*** 判斷是否還有下一個(gè)元素* @return*/@Overridepublic boolean hasNext() {if (payXiao != null && index < payXiao.size()){return true;}return false;}@Overridepublic Object next() {Object o = null;if (hasNext()){o = payXiao.get(index);// 每取走一個(gè)值,就把已訪問索引加1index++;}return o;}
}
Client
package day13迭代器Java實(shí)現(xiàn);import day13迭代器Java實(shí)現(xiàn).entity.PayModel;import java.util.Iterator;public class Client {public static void main(String[] args) {// 訪問集團(tuán)的工資列表PayDa payDa = new PayDa();// 先計(jì)算再獲取payDa.calcPay();
// List payList = payDa.getPayList();
// Iterator it = payList.iterator();System.out.println("大公司工資列表: ");
// while (it.hasNext()){
// PayModel next = (PayModel)it.next();
// System.out.println(next);
// }test(payDa.createIterator());// 訪問小公司的工資列表PayXiao payXiao = new PayXiao();payXiao.calcPay();
// PayModel[] pays = payXiao.getPays();System.out.println("小公司工資列表: ");test(payXiao.createIterator());}private static void test(Iterator it){// 判斷是否還有下一個(gè)元素while (it.hasNext()){PayModel next = (PayModel)it.next();System.out.println(next);}}
}
?解析:為什么要保留數(shù)據(jù)的IteratorImpl呢?因?yàn)閘ist有iterator方法可以直接調(diào)用,數(shù)組沒有要進(jìn)行轉(zhuǎn)變,怎么轉(zhuǎn)變呢?就是實(shí)現(xiàn)Iterator接口后重寫方法next和hasNext這兩個(gè)方法。以此來跟list相同就可以使用統(tǒng)一的迭代器了。
在Client中,大公司調(diào)用自身list的迭代器,小公司調(diào)用重寫后的迭代器
它new了一個(gè)Impl,這個(gè)Impl實(shí)現(xiàn)的就是java.util.iterator的迭代器且重寫了方法?
迭代器模式的優(yōu)點(diǎn)?
思考?
本質(zhì):
控制訪問聚合對象中的元素