8.迭代器模式
(1).概述
定义:
提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示(遍历)。
(2).结构
迭代器模式主要包含以下角色:
- 抽象聚合角色: 定义储存、添加,删除聚合元素以及创建迭代器对象的
接口
。 - 具体聚合角色: 实现抽象聚合类,返回一个具体的迭代器的实列。
- 抽象迭代器角色: 定义
访问和遍历聚合元素的接口
,通常包含 hasNext()、next()等方法。 - 具体迭代器角色:
实现抽象迭代器接口
中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
(3).案列实现:
eg: 定义一个可以存储学生对象的容器对象,将遍历该容器的功能交由迭代器实现,设计到的类如:
Student
package com.jsxs.behavioralModel.iterator; /** * @Author Jsxs * @Date 2023/4/24 12:02 * @PackageName:com.jsxs.behavioralModel.iterator * @ClassName: Student * @Description: TODO * @Version 1.0 */ public class Student { private String name; private String number; public String getName() { return name; } public Student(String name, String number) { this.name = name; this.number = number; } public void setName(String name) { this.name = name; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", number='" + number + '\'' + '}'; } }
抽象迭代器接口
package com.jsxs.behavioralModel.iterator; /** * @Author Jsxs * @Date 2023/4/24 12:03 * @PackageName:com.jsxs.behavioralModel.iterator * @ClassName: StudentIterator * @Description: TODO 抽象迭代器接口 * @Version 1.0 */ public interface StudentIterator { // 判断是否还有元素 boolean hasNext(); // 获取下一个元素 Student next(); }
具体迭代器
package com.jsxs.behavioralModel.iterator; import java.util.List; /** * @Author Jsxs * @Date 2023/4/24 12:05 * @PackageName:com.jsxs.behavioralModel.iterator * @ClassName: StudentInteratorIml * @Description: TODO 具体迭代器 * @Version 1.0 */ public class StudentInteratorIml implements StudentIterator{ private List<Student> list; public StudentInteratorIml(List<Student> list) { this.list = list; } // 记录位置 private int position=0; @Override public boolean hasNext() { return position<list.size(); //判断list集合中是否有元素 } @Override public Student next() { // 从集合中获取指定位置的元素 Student student = list.get(position); position++; return student; } }
抽象聚合角色
package com.jsxs.behavioralModel.iterator; /** * @Author Jsxs * @Date 2023/4/24 12:16 * @PackageName:com.jsxs.behavioralModel.iterator * @ClassName: StudentAggregate * @Description: TODO 抽象聚合角色 * @Version 1.0 */ public interface StudentAggregate { // 添加学生的功能 void addStudent(Student student); //删除学生的功能 void deleteStudent(Student student); // 获取迭代器的功能 StudentIterator getStudentIterator(); }
具体聚合角色
package com.jsxs.behavioralModel.iterator; import java.util.ArrayList; import java.util.List; /** * @Author Jsxs * @Date 2023/4/24 12:20 * @PackageName:com.jsxs.behavioralModel.iterator * @ClassName: StuedntAggergateImi * @Description: TODO 具体聚合角色 * @Version 1.0 */ public class StuedntAggergateImi implements StudentAggregate{ private List<Student> list=new ArrayList<Student>(); @Override public void addStudent(Student student) { list.add(student); } @Override public void deleteStudent(Student student) { list.remove(student); } @Override public StudentIterator getStudentIterator() { return new StudentInteratorIml(list); } }
测试
package com.jsxs.behavioralModel.iterator; /** * @Author Jsxs * @Date 2023/4/24 12:34 * @PackageName:com.jsxs.behavioralModel.iterator * @ClassName: Client * @Description: TODO * @Version 1.0 */ public class Client { public static void main(String[] args) { // 创建聚合对象 StuedntAggergateImi stuedntAggergateImi = new StuedntAggergateImi(); // 添加元素 stuedntAggergateImi.addStudent(new Student("JSXS","12122")); stuedntAggergateImi.addStudent(new Student("JSXS","12122")); stuedntAggergateImi.addStudent(new Student("JSXS","12122")); stuedntAggergateImi.addStudent(new Student("JSXS","12122")); // 遍历聚合对象 // (1).获取迭代器对象 StudentIterator studentIterator = stuedntAggergateImi.getStudentIterator(); // (2).遍历 while (studentIterator.hasNext()){ System.out.println(studentIterator.next().toString()); } } }
(4).优缺点
优点:
- 它支持以不同的方式遍历一个聚合对象,在同一个聚合对象上可以定义多种遍历方式。在迭代器模式中只需要用一个不同的迭代器来替换原有迭代器即可改变遍历算法,我们也可以自己定义迭代器的子类以支持新的遍历方式。
- 迭代器简化了聚合类。由于引入了迭代器,在原有的聚合对象中不需要再自行提供数据遍历等方法,这样可以简化聚合类的设计。
- 在迭代器模式中,由于引入了抽象层,增加新的聚合类和迭代器类都很方便,无需修改原有代码,满足 “
开闭原则
” 的要求。
缺点:
增加了类的个数,这在一定程度增加了系统的复杂性。
使用场景:
- 当需要为聚合对象提供多种遍历方式时。
- 当需要遍历不同的聚合结构提供一个统一的接口时。
- 当访问一个聚合对象的内容而无需暴露其内部细节的表示时。
(5).JDK源码解析
迭代器模式在Java的很多集合类被广泛应用。
List<String> list=new ArrayList<>(); Iterator<String> iterator=list.iiterator(); while(iterator.hasNext(){ System.out.print(iterator.next()) }
- List: 抽象聚合类
- ArrayList: 具体的聚合类
- Iterator: 抽象迭代器
- list.iterator(): 返回的实现了
Iterator
接口的具体迭代器对象。
9.访问者模式
(1).概述
定义:
封装一些作用于某种数据结构中的个元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。
(2).结构
访问者模式包含以下主要角色:
- 抽象访问者角色: 定义了对每一个元素(Element)访问的行为,它的参数就是可以访问的元素,
他的方法个数理论上来讲与元素个数的实现个数(Element的实现个数)是一样的
,从这点不难看出,访问者模式要求元素类的个数不能改变。 - 具体访问者角色: 给出对每一个元素访问时所产生的
具体行为
。 - 抽象元素角色: 定义了一个
接受访问者的方法
(accept),其意义是指,每一个元素都要可以被访问者访问。 - 具体元素角色:
提供接受访问方法的具体实现
,而这个具体的实现,通常情况下是使用访问者提供的访问该元素类的方法。 - 对象结构角色:
定义当中所提到的对象结构
,对象结构是一个抽象描述,具体点可以理解为一个具有容器性质或者符合对象特性的类,它会含有一组元素,并且可以迭代这些元素,供访问者访问。
(3).案列实现
给宠物喂食物:
现在养宠物的人特别多,我们就以这个为列子,当然宠物还分为狗、猫等,要给宠物喂食物的话,主任可以喂食物,其他人也可以喂食物。
- 访问者角色: 给宠物喂食物的人
- 具体访问者角色: 主人、其他人。
- 抽象元素角色: 动物抽象类。
- 具体元素角色: 宠物狗、宠物猫。
- 结构对象角色: 主人家。
抽象访问者角色
package com.jsxs.behavioralModel.vistor; /** * @Author Jsxs * @Date 2023/4/24 13:29 * @PackageName:com.jsxs.behavioralModel.vistor * @ClassName: Person * @Description: TODO 抽象访问者角色 * @Version 1.0 */ public interface Person { // 喂狗 void feed(Cat cat); //喂猫 void feed(Dog dog); }
抽象元素角色
package com.jsxs.behavioralModel.vistor; /** * @Author Jsxs * @Date 2023/4/24 13:30 * @PackageName:com.jsxs.behavioralModel.vistor * @ClassName: Animal * @Description: TODO 抽象元素角色 * @Version 1.0 */ public interface Animal { // 接受访问者访问的功能 void accept(Person person); }
具体元素角色
package com.jsxs.behavioralModel.vistor; /** * @Author Jsxs * @Date 2023/4/24 13:30 * @PackageName:com.jsxs.behavioralModel.vistor * @ClassName: Cat * @Description: TODO 具体元素角色 * @Version 1.0 */ public class Cat implements Animal{ @Override public void accept(Person person) { person.feed(this); System.out.println("好好吃饭 猫咪"); } }
package com.jsxs.behavioralModel.vistor; /** * @Author Jsxs * @Date 2023/4/24 13:30 * @PackageName:com.jsxs.behavioralModel.vistor * @ClassName: Dog * @Description: TODO 具体元素角色 * @Version 1.0 */ public class Dog implements Animal{ @Override public void accept(Person person) { person.feed(this); System.out.println("好好吃饭 狗"); } }
具体访问者角色
package com.jsxs.behavioralModel.vistor; /** * @Author Jsxs * @Date 2023/4/24 13:35 * @PackageName:com.jsxs.behavioralModel.vistor * @ClassName: Owner * @Description: TODO 具体访问角色 * @Version 1.0 */ public class Owner implements Person{ @Override public void feed(Cat cat) { System.out.println("主人喂猫"); } @Override public void feed(Dog dog) { System.out.println("主人喂狗"); } }
package com.jsxs.behavioralModel.vistor; /** * @Author Jsxs * @Date 2023/4/24 13:36 * @PackageName:com.jsxs.behavioralModel.vistor * @ClassName: SomeOne * @Description: TODO * @Version 1.0 */ public class SomeOne implements Person{ @Override public void feed(Cat cat) { System.out.println("非主人喂猫"); } @Override public void feed(Dog dog) { System.out.println("非主人喂狗"); } }
对象结构
package com.jsxs.behavioralModel.vistor; import java.util.ArrayList; import java.util.List; /** * @Author Jsxs * @Date 2023/4/24 13:38 * @PackageName:com.jsxs.behavioralModel.vistor * @ClassName: Home * @Description: TODO 对象结构类 * @Version 1.0 */ public class Home { // 声明一个独享 private List<Animal> animals= new ArrayList<Animal>(); // 添加元素的功能 public void add(Animal animal){ animals.add(animal); } // public void action(Person person){ // 遍历集合获取每一个元素 for (Animal animal : animals) { animal.accept(person); } } }
测试
package com.jsxs.behavioralModel.vistor; /** * @Author Jsxs * @Date 2023/4/24 13:42 * @PackageName:com.jsxs.behavioralModel.vistor * @ClassName: Client * @Description: TODO * @Version 1.0 */ public class Client { public static void main(String[] args) { Home home = new Home(); home.add(new Cat()); home.add(new Dog()); home.action(new Owner()); } }