设计模式学习笔记之迭代器模式

来源:互联网 发布:js递归调用方法 编辑:程序博客网 时间:2024/04/30 02:29

什么是迭代器模式呢?

迭代器模式就是提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。

理解起来是不是很抽象?我们下面马上举个例子!

很多玩LOL的玩家可能都知道,LOL在中国的联赛LPL联赛。



嗯,这个比赛的参赛俱乐部的管理组织就是大名鼎鼎的中国电子竞技俱乐部联盟(Association of China E-sports)简称ACE联盟。该组织负责国内职业电子竞技战队注册、管理、转会、赛事监督等多方面工作,并颁布职业联赛参赛俱乐部管理办法、职业选手个人行为规范等多个条例。

下面我们来建立一个LPL联系的两支参赛队在ACE的管理和介绍系统。这两支队伍分别是IG战队和WE战队。

我们先来构建一个参赛队员类:


//游戏选手类public class GamePlayer {//姓名和选手描述private String name,description;//是否为男性选手private boolean male;//身价private float salary;//初始化构造函数public GamePlayer(String name,String description,boolean male,float salary){this.name=name;this.description=description;this.male=male;this.salary=salary;}public String getName(){return name;}public String getDescription(){return description;}public float getSalary(){return salary;}public boolean isMale(){return male;}}


再来构建IG战队类


public class IgLolGameTeam {//最大上场队员数private final static int Max_Players=5;//队员统计public int numberOfplayer=0;//队员存储数组private GamePlayer[] gameplayers;//构造函数public IgLolGameTeam(){gameplayers=new GamePlayer[Max_Players] ;addPlayer("上单_957","A级",true,900000f);addPlayer("打野_Condi","A级",true,800000f);addPlayer("中单_xiye","S级",true,1500000f);addPlayer("AD_MyStic","S级",true,130000f);addPlayer("辅助_Zero","A级",true,800000f);}//添加队员函数private void addPlayer(String name, String description, boolean male,float salary) {GamePlayer gameplayer = new GamePlayer(name, description, male, salary);if(numberOfplayer>=Max_Players){System.err.println("sorry,menu is full!can not add another item");}else{gameplayers[numberOfplayer]=gameplayer;numberOfplayer++;}}//获取所有上场队员public GamePlayer[] getGamePlayers() {return gameplayers;}}


WE战队类


public class WeLolGameTeam {//队员存储数组private ArrayList<GamePlayer> gameplayers;//构造函数public WeLolGameTeam() {gameplayers = new ArrayList<GamePlayer>();addPlayer("上单_Duke","S级",true,2000000f);addPlayer("打野_Kid","A级",true,1000000f);addPlayer("中单_Rookie","S级",true,1500000f);addPlayer("AD_Rain","A级",true,90000f);addPlayer("辅助_Tabe","A级",true,900000f);}//添加队员函数private void addPlayer(String name, String description, boolean male,float salary) {GamePlayer gameplayer = new GamePlayer(name, description, male, salary);gameplayers.add(gameplayer);}//获取所有上场队员public ArrayList<GamePlayer> getGamePlayers() {return gameplayers;}}


我们可以看到,由于每个战队的管理风格不同,所以各战队间的存储队员的数据结构也各不相同,WE用的是动态数组,而IG战队使用的就是一般的数组。


下面我们来构建ACE联盟类:


public class  AssociationOfChinaEsports {//战队private IgLolGameTeam mIgLolGameTeam;private WeLolGameTeam mWeLolGameTeam;//队员存储private ArrayList<GamePlayer> gameplayers_we;private GamePlayer[] gameplayers_ig;//构造函数public AssociationOfChinaEsports() {//战队初始化mWeLolGameTeam = new WeLolGameTeam();gameplayers_we = mWeLolGameTeam.getGamePlayers();mIgLolGameTeam = new IgLolGameTeam();gameplayers_ig = mIgLolGameTeam.getGamePlayers();}//打印队员信息public void printPlayer(){GamePlayer gameplayer;System.out.println("IG战队队员:");for (int i = 0, len = gameplayers_we.size(); i < len; i++) {gameplayer = gameplayers_we.get(i);System.out.println(gameplayer.getName() + "***" +gameplayer.isMale() + "***" + gameplayer.getDescription());}System.out.println("=========================================");System.out.println("WE战队队员:");for (int i = 0, len = mIgLolGameTeam.numberOfplayer; i < len; i++){gameplayer = gameplayers_ig[i];System.out.println(gameplayer.getName() + "***" +gameplayer.isMale() + "***" + gameplayer.getDescription());}}}

下面我们用测试函数输出一下,我们每个队员的信息


public class MainTest {public static void main(String[] args) {AssociationOfChinaEsports mAssociationOfChinaEsports=new AssociationOfChinaEsports();mAssociationOfChinaEsports.printPlayer();}}




在这个例子中我们可能会发现一些问题:由于各个战队之间的管理不同(存储),导致在ACE里不能进行统一的处理,这样会过多的暴露各个战队的机密信息,比如各个选手的工资水平,而这些信息对于每个战队来讲都是绝密的。

那我们应该怎么办呢?这里就应该使用迭代器模式去处理这个问题了。

首先,我们先定义一个迭代器接口


//迭代器接口public interface Iterator {//判断是否有下一个队员public boolean hasNext();//返回下一个队员public Object next();}


然后重新构建两个战队的类,并用内部类的形式实现迭代器

IG:


public class IgLolGameTeam {//最大上场队员数private final static int Max_Players=5;//队员统计public int numberOfplayer=0;//队员存储数组private GamePlayer[] gameplayers;//构造函数public IgLolGameTeam(){gameplayers=new GamePlayer[Max_Players] ;addPlayer("上单_957","A级",true,900000f);addPlayer("打野_Condi","A级",true,800000f);addPlayer("中单_xiye","S级",true,1500000f);addPlayer("AD_MyStic","S级",true,130000f);addPlayer("辅助_Zero","A级",true,800000f);}//添加队员函数private void addPlayer(String name, String description, boolean male,float salary) {GamePlayer gameplayer = new GamePlayer(name, description, male, salary);if(numberOfplayer>=Max_Players){System.err.println("sorry,menu is full!can not add another item");}else{gameplayers[numberOfplayer]=gameplayer;numberOfplayer++;}}//获取迭代器public Iterator getIterator(){return new IgLolGameTeamIterator() ;}//实现迭代器class IgLolGameTeamIterator implements Iterator {private int position;public IgLolGameTeamIterator() {position = 0;}@Overridepublic boolean hasNext() {// TODO Auto-generated method stubif (position < numberOfplayer) {return true;}return false;}@Overridepublic Object next() {// TODO Auto-generated method stubGamePlayer gameplayer_sub = gameplayers[position];position++;return gameplayer_sub;}};}

WE


public class WeLolGameTeam {//队员存储数组private ArrayList<GamePlayer> gameplayers;//构造函数public WeLolGameTeam() {gameplayers = new ArrayList<GamePlayer>();addPlayer("上单_Duke","S级",true,2000000f);addPlayer("打野_Kid","A级",true,1000000f);addPlayer("中单_Rookie","S级",true,1500000f);addPlayer("AD_Rain","A级",true,90000f);addPlayer("辅助_Tabe","A级",true,900000f);}//添加队员函数private void addPlayer(String name, String description, boolean male,float salary) {GamePlayer gameplayer = new GamePlayer(name, description, male, salary);gameplayers.add(gameplayer);}//获取迭代器public Iterator getIterator() {return new WeLolGameTeamIterator();}//实现迭代器class WeLolGameTeamIterator implements  Iterator{private int position=0;public WeLolGameTeamIterator(){  position=0;} @Overridepublic boolean hasNext()  {// TODO Auto-generated method stubif(position<gameplayers.size()){return true;}return false;}@Overridepublic Object next() {// TODO Auto-generated method stubGamePlayer gameplayer_sub =gameplayers.get(position);position++;return gameplayer_sub;}};}


然后是ACE联盟来处理这些迭代器


public class  AssociationOfChinaEsports {private ArrayList<Iterator> iterators=new ArrayList<Iterator>();public AssociationOfChinaEsports() {}//添加迭代器public void addIterator(Iterator iterator){iterators.add(iterator);}//打印队员信息public void printMenu() {Iterator iterator;GamePlayer menuItem;for (int i = 0, len = iterators.size(); i < len; i++) {iterator = iterators.get(i);System.out.println("战队介绍:");while(iterator.hasNext()){menuItem=(GamePlayer) iterator.next();System.out.println(menuItem.getName() + "***" +menuItem.isMale()+"***" + menuItem.getDescription());}System.out.println("=============================================");}}}

最后我们来测试一下


public class MainTest {public static void main(String[] args) {AssociationOfChinaEsports mAssociationOfChinaEsports=new AssociationOfChinaEsports();IgLolGameTeam mIgLolGameTeam = new IgLolGameTeam();WeLolGameTeam mWeLolGameTeam = new WeLolGameTeam();mAssociationOfChinaEsports.addIterator(mIgLolGameTeam.getIterator());mAssociationOfChinaEsports.addIterator(mWeLolGameTeam.getIterator());mAssociationOfChinaEsports.printMenu();}}



这回我们可以清晰的看见,在ACE联盟类中,每个战队都没有暴露他们的细节,这就是迭代器模式的有点


迭代器模式的优点有:
1.简化了遍历方式,用户用起来简单了。
2.可以进行多种遍历方式的使用,方便了对集合的遍历。
3.封装性良好,只需要得到迭代器遍历,而对于遍历算法则不用去关心,并且更好的封装了内部的信息细节。
迭代器模式的缺点:
1.对于比较简单的遍历,使用较为繁琐。


迭代器的适用场景:

1.对于容器的自定义迭代。


=============================================================


最后为lpl的中国战队加油!在今年的S8世界总决赛中,希望他们能有个好成绩!!
















1 0
原创粉丝点击