迭代器模式&观察者模式

发布于:2024-06-28 ⋅ 阅读:(20) ⋅ 点赞:(0)

1.引出迭代器模式

1.展示院系结构

image-20240615212257547

2.传统方式

image-20240615212357982

2.迭代器模式解决院系结构展示问题

1.基本介绍

image-20240615212618599

2.原理类图

image-20240615213958769

3.类图

image-20240616200949550

4.代码实现
1.Department.java 存储信息的对象
package com.sun;

/**
 * Description: 系
 * @Author sun
 * @Create 2024/6/16 20:11
 * @Version 1.0
 */
public class Department {

    private String name;
    private String desc;

    public Department(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}
2.College.java 被迭代的类型接口
package com.sun;

import java.util.Iterator;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/16 20:31
 * @Version 1.0
 */
public interface College {

    // 获取大学的名字
    String getName();

    // 添加一个系
    void addDepartment(String name, String desc);

    // 创建迭代器
    Iterator createIterator();

}
3.ComputerCollege.java 被迭代的具体实现类,存储数据并将其在创建迭代器的时候传进去
package com.sun;

import java.util.Iterator;

/**
 * Description: 具体的学院
 * @Author sun
 * @Create 2024/6/16 20:35
 * @Version 1.0
 */
public class ComputerCollege implements College {

    // 数组类型的元素
    Department[] departments;
    // 保存当前数组的对象个数
    int numOfDepartment = 0;

    /**
     * 初始化数组
     */
    public ComputerCollege() {
        departments = new Department[3];
        addDepartment("java", "java");
        addDepartment("python", "python");
        addDepartment("go", "go");
    }

    /**
     * 获取当前学院的名字
     * @return
     */
    @Override
    public String getName() {
        return "计算机学院";
    }

    /**
     * 添加要遍历的元素
     * @param name
     * @param desc
     */
    @Override
    public void addDepartment(String name, String desc) {
        Department department = new Department(name, desc);
        departments[numOfDepartment++] = department;
    }

    /**
     * 创建迭代器
     * @return
     */
    @Override
    public Iterator createIterator() {
        // 创建一个迭代器并将元素放进去
        return new ComputerCollegeIterator(departments);
    }
}
4.ComputerCollegeIterator.java 被实现的具体类的迭代器
package com.sun;

import java.util.Iterator;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/16 20:13
 * @Version 1.0
 */
public class ComputerCollegeIterator implements Iterator {

    // 构造器聚合Department,也就是要遍历的元素,这里的是数组的形式
    Department[] departments;
    // 遍历的位置
    int position = 0;

    public ComputerCollegeIterator(Department[] departments) {
        this.departments = departments;
    }

    /**
     * 数组的形式判断是否有下一个元素,其实就是判断当前位置有没有元素
     * @return
     */
    @Override
    public boolean hasNext() {
        if(position >= departments.length || departments[position] == null) {
            return false;
        }
        return true;
    }

    /**
     * 数组的形式取出下一个元素,其实就是取出当前元素,然后将下标加一
     * @return
     */
    @Override
    public Object next() {
        Department department = departments[position];
        position += 1;
        return department;
    }

    /**
     * 删除的方法默认空实现
     */
    @Override
    public void remove() {
        Iterator.super.remove();
    }
}
5.InfoCollege.java 被迭代的具体类型
package com.sun;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * Description: 具体的学院
 * @Author sun
 * @Create 2024/6/16 20:41
 * @Version 1.0
 */
public class InfoCollege implements College{

    // 集合类型的元素
    List<Department> departmentList;

    /**
     * 初始化具体的学院信息
     */
    public InfoCollege() {
        departmentList = new LinkedList<>();
        addDepartment("信息安全", "信息安全");
        addDepartment("网络安全", "网络安全");
        addDepartment("服务器安全", "服务器安全");
    }

    /**
     * 获取名称
     * @return
     */
    @Override
    public String getName() {
        return "信息工程学院";
    }

    /**
     * 集合的方式添加元素
     * @param name
     * @param desc
     */
    @Override
    public void addDepartment(String name, String desc) {
        Department department = new Department(name, desc);
        departmentList.add(department);
    }

    /**
     * 创建迭代器
     * @return
     */
    @Override
    public Iterator createIterator() {
        return new InfoColleageIterator(departmentList);
    }
}
6.InfoColleageIterator.java 具体的迭代器
package com.sun;

import java.util.Iterator;
import java.util.List;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/16 20:25
 * @Version 1.0
 */
public class InfoColleageIterator implements Iterator {

    // 集合类型的
    List<Department> departments;
    // 未遍历元素的前一个位置
    int index = -1;

    public InfoColleageIterator(List<Department> departments) {
        this.departments = departments;
    }

    /**
     * 集合的方式判断是否有下一个位置
     * @return
     */
    @Override
    public boolean hasNext() {
        if (index >= departments.size() - 1) {
            return false;
        }
        // 如果有下一个位置,直接指向下一个位置
        index += 1;
        return true;
    }

    /**
     * 集合的方式获取下一个元素
     * @return
     */
    @Override
    public Object next() {
        return departments.get(index);
    }

    /**
     * 删除方法空实现
     */
    @Override
    public void remove() {
        Iterator.super.remove();
    }
}
7.OutputImpl.java 统一输出信息的类
package com.sun;

import java.util.Iterator;
import java.util.List;

/**
 * Description: 输出
 * @Author sun
 * @Create 2024/6/16 20:46
 * @Version 1.0
 */
public class OutputImpl {

    // 构造器聚合学院集合,才能够输出
    List<College> collegeList;

    public OutputImpl(List<College> collegeList) {
        this.collegeList = collegeList;
    }

    // 遍历所有学院,然后输出各个学院的系
    public void printCollege() {
        // 从学院集合中得到各个学院的迭代器,然后进行遍历
        for (College college : collegeList) {
            // 得到学院
            System.out.println("=====" + college.getName() + "=====");
            // 得到学院的迭代器
            Iterator iterator = college.createIterator();
            // 遍历
            printDepartment(iterator);
        }
    }

    // 输出学院,输出系
    public void printDepartment(Iterator iterator) {
        // 根据得到的迭代器进行遍历
        while (iterator.hasNext()) {
            Department next = (Department) iterator.next();
            System.out.println(next.getName());
        }
    }

}
8.Client.java 客户端
package com.sun;

import java.util.LinkedList;
import java.util.List;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/16 20:59
 * @Version 1.0
 */
public class Client {

    public static void main(String[] args) {
        // 创建两个学院,放到集合中
        List<College> collegeList = new LinkedList<>();

        collegeList.add(new ComputerCollege());
        collegeList.add(new InfoCollege());

        // 遍历
        OutputImpl output = new OutputImpl(collegeList);
        output.printCollege();
    }
}
5.注意事项和细节

image-20240617195403899

3.迭代器模式在ArrayList的应用

观察者模式

1.引出观察者模式

1.天气预报项目需求

image-20240617195703024

2.普通方案

image-20240617200144645

image-20240617200256420

3.普通方案问题分析

image-20240617201005774

2.观察者模式解决天气预报

1.原理分析

image-20240617201208773

image-20240617201218388

2.类图

image-20240617204226600

3.代码实现
1.Observer.java 观察者接口,可以更新自己的信息
package com.sun;

/**
 * Description: 观察者接口
 * @Author sun
 * @Create 2024/6/17 20:28
 * @Version 1.0
 */
public interface Observer {

    void update(float temperature, float pressure, float humidity);

}
2.CurrentConditions.java 具体的观察者
package com.sun;

/**
 * Description: 具体的观察者
 * @Author sun
 * @Create 2024/6/17 20:30
 * @Version 1.0
 */
public class CurrentConditions implements Observer{

    private float temperature;

    private float pressure;

    private float humidity;

    /**
     * 更新并显示数据
     * @param temperature
     * @param pressure
     * @param humidity
     */
    @Override
    public void update(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        display();
    }

    /**
     * 显示
     */
    public void display() {
        System.out.println("Today's temperature: " + temperature);
        System.out.println("Today's pressure: " + pressure);
        System.out.println("Today's humidity: " + humidity);
    }

}
3.Subject.java 信息发布者的接口
package com.sun;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/17 20:27
 * @Version 1.0
 */
public interface Subject {

    void registerObserver(Observer o);

    void removeObserver(Observer o);

    void notifyObservers();

}
4.WeatherData.java 具体的信息发布者,一旦更新信息就会更新观察者的信息
package com.sun;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Description: 包含最新的天气,和观察者集合,当更新时会依次通知各个观察者
 * @Author sun
 * @Create 2024/6/17 20:36
 * @Version 1.0
 */
public class WeatherData implements Subject{

    /*
    天气信息
     */
    private float temperature;

    private float pressure;

    private float humidity;

    /*
    观察者集合
     */
    private List<Observer> observerList;

    /**
     * 初始化
     */
    public WeatherData() {
        observerList = new ArrayList<>();
    }

    /**
     * 设置数据
     * @param temperature
     * @param pressure
     * @param humidity
     */
    public void setData(float temperature, float pressure, float humidity) {
        this.humidity = humidity;
        this.pressure = pressure;
        this.temperature = temperature;
        changeData();
    }

    /**
     * 当数据改变时会通知所有的观察者
     */
    public void changeData() {
        notifyObservers();
    }

    /**
     * 注册观察者
     * @param o
     */
    @Override
    public void registerObserver(Observer o) {
        observerList.add(o);
    }

    /**
     * 移除观察者
     * @param o
     */
    @Override
    public void removeObserver(Observer o) {
        observerList.remove(o);
    }

    /**
     * 遍历所有的观察者并通知
     */
    @Override
    public void notifyObservers() {
        // 这里使用迭代器遍历(只要能遍历就可以)
        Iterator<Observer> iterator = observerList.iterator();
        while (iterator.hasNext()) {
            Observer next = iterator.next();
            // 更新
            next.update(temperature, pressure, humidity);
        }
    }

}
5.Client.java
package com.sun;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/17 21:02
 * @Version 1.0
 */
public class Client {

    public static void main(String[] args) {
        // 创建一个有天气数据的对象
        WeatherData weatherData = new WeatherData();
        // 创建观察者
        CurrentConditions currentConditions = new CurrentConditions();
        // 注册观察者
        weatherData.registerObserver(currentConditions);
        // 修改天气状况
        weatherData.setData(200, 200, 200);
        // 再修改一下天气状况
        weatherData.setData(100, 100, 100);
    }

}
6.结果

image-20240618201732219

3.观察者模式在JDK的Observable类中的使用

image-20240618201819188