设计模式的创建模式,设计模式 创建型模式
在迭代器模式之前,我们的电视调节频道需要通过电视按钮来控制。没有遥控器。如果我们想换频道,我们只能多次转动按钮。
越来越多的先进电视机问世,现在已经有
电视遥控器
部电话。用电视遥控器调节电台。这时候就不需要直接操作电视了。我们可以使用遥控器通过
将电视机看成一个存储电视频道的集合对象
操作电视中的电视频道集合。比如回到上一个频道,跳到下一个频道,跳到指定频道等等。遥控器非常方便我们操作电视频道。用户并不需要知道这些频道到底如何存储在电视机中。
编写一个具体的案例:展示学校结构的程序。这是需求。要在一个页面上显示一个学校的院系组成,一个学校有多个学院,一个学院有多个院系。分析:所有学院都有增加院系的功能。遍历方法hasNext () next)等等。这违反了
既负责存储和管理数据,又负责遍历数据
,因为聚合类非常大,实现代码太长,无法测试和维护。这个时候,我们可能会这么想。因为学院多,学院可以打包成接口,但是这个接口充满了很多方法,不利于子类的实现,“
单一职责原则
解决方案:解决方案之一是将聚合类中负责数据遍历的方法提取出来,封装在一个特殊的类中,实现数据存储和数据遍历的分离,允许操作而不暴露聚合类的内部属性。这就是迭代器模型的意图。
引入基本迭代器模式是一种常见的设计模式,属于行为模式。如果我们的集合元素以不同的方式实现,有数组和java集合类。
或者,如果客户机想要遍历这些集合元素,它也可以使用各种遍历方法。
方法,它将公开元素的内部结构。可以考虑用迭代器模式来解决。迭代器类型为遍历集合元素提供了统一的接口,并以一致的方式遍历集合元素。
您可能不知道集合对象的底部表示,即它的内部结构。原理类图:
角色分析:迭代器:迭代器接口。表示系统提供的hasNext,Next,removeConcreteIterator)。的具体迭代器类管理光标在特定迭代器的聚合对象中的当前位置。在具体实现中,通常通过游标将游标记录到aggregate对象中的aggregate类中:客户端和具体的aggregate解耦为aggregate的具体Aggregate所拥有的对象集合:
接口隔离原则”。
/* * * College * * @ authorrxdsbon 2020/2/17 */public interface College { public string GetName();//添加系统方法PublicVoidadDepartment(字符串名,字符串des);返回//迭代器,点击公共迭代器create iterator();}
聚合类:
/* * *计算机学院* * @ authorrxdsbon 2020/2/17 */public classcomputercollege实现学校{department []院系;int numOfDepartment=0;//当前数组对象数公共计算机学院(){ departments=new department[5];//计算机学院有五个系,adddepartment(JAVA , JAVA驱牛);加(PHP,)经典);加( c ,没关系);Add (python,“智能”);加(走,牛);} @ override public string getname(){ return Computer College);//计算机学院有本科生@ overridepublicadaddepartment(string name,string des)department department=new department)name,dednumofdepartment=1;} @覆盖公共迭代器
create iterator(){ return new ComputerCollegeIterator(departments);}}
信息学院
/** * 信息学院* * @作者rxdsb于2020年2月17日*/公开课信息学院实现学院列表部门部门;//int numOfDepartment=0;//保存当前数组对象个数public info college(){ departments=new ArrayList department();//计算机学院有5个系添加部门(信息安全, JAVA牛逼);添加部门(网络安全,经典);添加部门(服务器安全,还好);添加部门(数据库安全,智能);} @覆盖公共字符串getName() { return 计算机学院;} //给计算机学院添加系@ Override public void add Department(String name,String des){ Department Department=new Department(name,des);部门. add(部门);//numOfDepartment=1;} @覆盖公共迭代器create Iterator(){返回新的InfoCollegeIterator(部门);}}
学院下面的系:
/** * 系*学校-学院-系* @ 2020/2/17作者rxdsb */公共课系{私串名;私有字符串数据加密标准公共部门(字符串名,字符串des){ this。name=名称;this.des=des}公共字符串getName(){ return name;} public void set name(String name){ this。name=名称;}公共字符串get des(){ return des;} public void setDes(String des){ this。des=des}}
迭代器类:
计算机学院迭代器
/* * * * @作者rxdsb on 2020/2/17 * ComputerCollegeIterator:计算机学院迭代器, * 遍历计算机学院下的系*/公共类计算机学院实现迭代器{ /* *这里需要知道部门以怎样的方式存放* * */部门[]部门;int position=0;//遍历的位置public ComputerCollegeIterator(Department[]departments){ this。部门=部门;} @ Override public boolean有next(){ if(position=departments。长度 部门[职位]==空){返回false }否则{返回true } } @覆盖公共对象next(){ Department部门=部门[职位];位置=1;退货部门;} @覆盖公共void remove() { }}信息学院迭代器:
/* * * * @作者rxdsb on 2020/2/17 * ComputerCollegeIterator:信息学院迭代器, * 遍历信息学院下的系*/公共类InfoCollegeIterator实现迭代器{ /* *这里需要知道部门以怎样的方式存放* * */列表部门部门;int position=-1;//索引public InfoCollegeIterator(列出部门departments){ this。部门=部门;} @ Override public boolean hasNext(){ if(position=departments。size()-1){返回false} else { position=1;返回true } } @覆盖公共对象next(){返回部门。get(位置);} @覆盖公共void remove() { }}
输出信息类:
/* * * * @作者rxdsb on 2020/2/17 *输出信息类*/公共课输出类{列出学院院校;public output class(list college colleges){ this . colleges=colleges;}//遍历公共void打印部门(iterator迭代器){ while(iterator . has next()){ department department=(department)iterator . next();system . out . println( department . getname()= department . getname());} }//遍历学院集合,输出所有学院的public void printCollege() {//此时不需要传入迭代器进行遍历。//学院通过使用列表集合实现了iterator iterator college iterator=colleges . iterator();While(iterator.hasNext()){ //拿出一个College College=iterator . next();system . out . println(========= college . getname()===);print department(college . create iterator());} }}
测试类:
/* * * * @ author rxdsb on 2020/2/17 */public class Client { public static void main(String[]args){ list college colleges=new ArrayList college();学院computer college=new computer college();学院info college=new info college();colleges.add(计算机学院);colleges . add(info college);output class output class=new output class(colleges);output class . print college();}}结果截图:
代码分析:如果需要添加一个新的具体聚合类,只需要添加一个新的聚合子类和一个新的具体迭代器类。原类库代码不需要修改,符合“开闭原则”;
如果需要为聚合类替换一个迭代器,只需要添加一个新的具体迭代器类作为抽象迭代器类的子类,重新实现遍历方法即可。原迭代器代码不需要修改,也符合“开闭原则”。
但如果要给迭代器增加新的方法,就需要修改抽象迭代器源代码,这就违背了“开闭原则”。
JDK数组列表集合中迭代器模式的源代码分析
角色分析描述
内部Itr类作为实现迭代器的类,内部List类作为ArrayList作为聚合接口。它包含一个iterator()方法,并返回一个iterator对象。ArrayList是实现聚合接口列表的子类,实现了迭代器()。iterator()迭代器系统提供迭代器模式,解决不同集合的统一遍历问题(ArrayList,LinkedList)
优点
。提供一个统一的方法来遍历对象,以便客户可以使用一种方法来遍历对象,而不用考虑聚合的类型。为了隐藏聚合的内部结构,客户端在遍历聚合时只能得到迭代器,而不知道聚合的具体构成。提供了一种设计思想,即一个类应该只有一个变更原因(称为单一责任
原理)。在聚合类中,我们分离迭代器,即管理对象集和遍历对象集。
分离的责任,从而使集合发生变化,只影响聚合对象。如果遍历模式改变,它只影响迭代器。迭代器模式
缺点
适用于显示一组相似的对象或遍历一组相同的对象。每个聚合对象都需要一个迭代器,这会生成多个迭代器不好管理的类。