Java设计模式(访问者模式-迭代器模式-观察者模式-中介者模式)

本文详细介绍了四种常用的设计模式:访问者模式用于封装数据结构上的操作,降低耦合;迭代器模式提供遍历集合的统一接口,隐藏内部结构;观察者模式实现了一对多的依赖关系,使得对象间可以松耦合地通信;中介者模式减少类之间的交互复杂性。通过实例代码展示了这些模式的工作原理和应用场景。
摘要由CSDN通过智能技术生成

1.访问者模式

1.1 访问者模式概述

(1)基本介绍

①访问者(Visitor)模式:封装一些作用于某种数据结构的各元素的操作。
	它可以在不改变数据结构的前提下定义作用于这些元素的新操作

②主要将数据结构和数据操作分离,解决数据结构和数据耦合性问题

③基本工作原理:在被访问的类里面加一个提供对外接待访问者的接口

(2) 原理类图
在这里插入图片描述
Visitor:是抽象访问者,为该对象结构中的ConcretElement的每一个类声明一个Visit操作
ConcreteVisitor:是一个具体的访问值,实现每个有Visitor声明的操作,是每个操作实现的部分
ObjectStrutrue:能枚举它的元素,可以提供一个高层的接口,用来允许访问者访问元素
Elmement:定义一个accept方法,接收一个访问者对象
ConcreteElement:为具体元素,实现了accept方法

(3) 代码类图
在这里插入图片描述

1.2 代码理解

1.Action

package com.pattern.设计模式.访问者模式;

public abstract class Action {
    // 得到男性的测评结果
    public abstract void getManResult(Man man);

    // 得到女性的测评
    public abstract void getWomanResult(Woman woman);
}

2.Success

package com.pattern.设计模式.访问者模式;

public class Success extends Action{
    @Override
    public void getManResult(Man man) {
        System.out.println(man.getName() + "给的是:成功");
    }

    @Override
    public void getWomanResult(Woman woman) {
        System.out.println("女人给的是Success");
    }
}

3.Fail

package com.pattern.设计模式.访问者模式;

public class Fail extends Action{
    @Override
    public void getManResult(Man man) {
        System.out.println("男人给了失败");
    }

    @Override
    public void getWomanResult(Woman woman) {
        System.out.println("女人给了失败");
    }
}

4.Person

package com.pattern.设计模式.访问者模式;

public abstract class Person {
    // 提供一个方法 让访问者可以访问
    public abstract void accept(Action action);
}

5.Man

package com.pattern.设计模式.访问者模式;

public class Man extends Person{

    private String name;

    public Man() {
    }

    public Man(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Man{" +
                "name='" + name + '\'' +
                '}';
    }

    @Override
    public void accept(Action action) {
        action.getManResult(this);
    }
}

6.Woman

package com.pattern.设计模式.访问者模式;


/**这里使用了双分派,即先在客户端程序中,将具体状态作为参数传递给Woman(第一次分派)
 然后Woman类调用作为参数的 具体方法 中方法getWomanResult,同时将自己(this)作为参数传入
 完成第二次分派
 */

public class Woman extends Person{
    @Override
    public void accept(Action action) {
        action.getWomanResult(this);
    }
}

7.ObjectStructure

package com.pattern.设计模式.访问者模式;

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

// 数据结构 管理了很多人
public class ObjectStructure {
    // 聚合一个集合
    private List<Person> list = new ArrayList<>();

    // 增加到list
    public void attach(Person person){
        list.add(person);
    }

    // 移除
    public void detach(Person person){
        list.remove(person);
    }

    // 显示测评情况
    public void disPlay(Action action){
        for (Person person:list){
            person.accept(action);
        }
    }

}

8.Test

package com.pattern.设计模式.访问者模式;

public class Test {
    public static void main(String[] args) {
        // 创建ObjectStructure对象
        ObjectStructure objectStructure = new ObjectStructure();

        // 增加几个man进入
        objectStructure.attach(new Man("李白"));
        objectStructure.attach(new Man("杜甫"));
        objectStructure.attach(new Man("李清照"));

        // 给一个成功
        Success success = new Success();
        objectStructure.disPlay(success);

        // 给失败
        Fail fail = new Fail();
        objectStructure.disPlay(fail);
    }
}

2.迭代器模式

2.1 迭代器模式概述

(1)基本介绍

①迭代器模式是常用的模式,属于行为型模式

②如果我们的集合元素是用不同的方式实现的,有数组,还有java的集合类,
	或者还有其他方式,当客户端要遍历这些集合元素的时候,就会使用多种
	遍历方式,而且还会暴露元素的内部结构,可以考虑迭代器模式,

③迭代器模式,提供一种遍历集合元素的统一接口,用一致的方法遍历集合
	元素,不需要知道集合对象的底层表示,即不暴露其内部的结构

(2)原理类图
在这里插入图片描述
Iterator:迭代器接口,系统提供,方法hasNext,next,remove
ConcreteIterator:具体的迭代器类,管理迭代
Aggregate:一个统一的聚合接口,将客户端和具体聚合解耦
ConcreteAggregate:具体的聚合持有对象集合,并提供一个方法,返回一个迭代器,该迭代器可以正确遍历集合
Client:客户端Iterator和Aggregate依赖子类

(3)代码类图
在这里插入图片描述
(4)JDK的ArrayList集合用到了迭代器模式
在这里插入图片描述
在这里插入图片描述

2.2 代码理解

1.College

package com.pattern.设计模式.迭代器模式;

import java.util.Iterator;

public interface College {

    public String getName();

    // 增加系
    public void add(String name, String desc);

    // 返回一个迭代器 遍历
    public Iterator createIterator();
}

2.ComputerCollege

package com.pattern.设计模式.迭代器模式;

import java.util.Iterator;

public class ComputerCollege implements College{

    Department[] departments;
    int number = 0;  // 保存当前数组的个数

    public ComputerCollege() {
        departments = new Department[5];
        add("计算机应用", "ok");
        add("计算机网络", "ok");
        add("信息工程", "ok");

    }

    @Override
    public String getName() {
        return "计算机学院";

    }

    @Override
    public void add(String name, String desc) {
        Department department = new Department(name, desc);
        departments[number] = department;
        number += 1;

    }

    @Override
    public Iterator createIterator() {
        return new ComputerCollegeIterator(departments);

    }
}

3.InfoCollege

package com.pattern.设计模式.迭代器模式;

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

public class InfoCollege implements College{

    List<Department> departmentList;

    public InfoCollege(){
        departmentList = new ArrayList<Department>();
       add("信息1", "NO");
       add("信息2", "NO");
       add("信息3", "NO");
    }
    @Override
    public String getName() {
        return "信息工程学院";
    }

    @Override
    public void add(String name, String desc) {
        Department department = new Department(name, desc);
        departmentList.add(department);
    }

    @Override
    public Iterator createIterator() {
        return new InfoCollegeIterator(departmentList);
    }
}

4.Department

package com.pattern.设计模式.迭代器模式;

public class Department {

    private String name;
    private String desc;

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

    public Department() {
    }

    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;
    }

    @Override
    public String toString() {
        return "Department{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

5.InfoCollegeIterator

package com.pattern.设计模式.迭代器模式;

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

public class InfoCollegeIterator implements Iterator {

    // 这个以list形式存放
    List<Department> departments;
    int index = -1; // 索引

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

    // 判断有没有下一个元素
    @Override
    public boolean hasNext() {
        if (index >= departments.size() - 1){
            return false;
        }else {
            index += 1;
            return true;

        }
    }

    //
    @Override
    public Object next() {
        return departments.get(index);

    }

    public void remove(){
        // null实现
    }
}

6.ComputerCollegeIterator

package com.pattern.设计模式.迭代器模式;

import java.util.Iterator;

public class ComputerCollegeIterator implements Iterator {

    // 这里我们需要Department 是以怎样的方式存放的
    Department[] departments;
    int position = 0;  // 遍历的位置

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

    // 判断是否还有下一个元素
    @Override
    public boolean hasNext() {

        if (position >= departments.length || departments[position] == null){
            return false;
        }else {
            return true;

        }
    }

    @Override
    public Object next() {
        Department department = departments[position];
        position += 1;
        return department;
    }

    public void remove(){
        // 空实现
    }

}

package com.pattern.设计模式.迭代器模式;

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

public class OutputImpl {

    // 学院集合
    List<College> colleges;

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

    }

    // 遍历所有的学院,然后再调用printDepartment 输出各个系
    public void printCollege(){
        // 从colleges中取出所有学院
        Iterator<College> iterator = colleges.iterator();
        while (iterator.hasNext()){
            // 取出一个学院
            College college = iterator.next();
            System.out.println("<<<<<<<<<<<" + college.getName() + ">>>>>>>>>>");
            // 得到对应的迭代器
            printDepartment(college.createIterator());

        }
    }

    // 输出系
    public void printDepartment(Iterator iterator){
        while (iterator.hasNext()){
            Department next = (Department) iterator.next();
            System.out.println(next.getName());
        }
    }
}

9.test

package com.pattern.设计模式.迭代器模式;

import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {
        ArrayList<College> colleges = new ArrayList<>();

        ComputerCollege computerCollege = new ComputerCollege();
        InfoCollege infoCollege = new InfoCollege();

        colleges.add(computerCollege);
        colleges.add(infoCollege);

        OutputImpl output = new OutputImpl(colleges);
        output.printCollege();
    }
}

3.观察者模式

3.1 观察者模式概述

(1)基本介绍

①观察者模式(又被称为发布-订阅模式,属于行为型模式的一种,它定义了
	一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这
	个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更
	新自己

(2)代码类图
在这里插入图片描述
Subject:用于注册观察者。观察者使用此接口注册为观察者,并从观察者中移除自身。

Observer:观察者接口定义了一个更新接口,观察者应被通知主题的更改。所有的观察者都需要实现观察者接口。这个接口有一个update()方法,当主题(Subject)的状态改变时调用它。

WeatherData:存储CurrentConditions对象的兴趣状态。当状态改变时,它会向观察者发送通知。具体的主题总是实现主题接口。notifyObservers()方法用于在状态更改时更新所有当前的观察者。

CurrentConditions:维护对具体主题对象的引用,并实现Observer接口。每个观察者注册一个具体的主题来接收更新。

(3)JDK中的Observable用到了观察者模式
在这里插入图片描述

3.2 代码理解

1.Subject

package com.pattern.设计模式.观察者模式;

// 让WeatherData实现
public interface Subject {

    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObserver();
}

2.WeatherData

package com.pattern.设计模式.观察者模式;

import java.util.ArrayList;

/**
 * 含有观察者集合,用ArrayList存储
 * 当数据有更新时,就主动调用,通知所有的接入方。
 */
public class WeatherData implements Subject{
    private float temperature;
    private float pressure;
    private float humidity;
    // 观察者集合
    private ArrayList<Observer> observers;

    public WeatherData() {
        observers = new ArrayList<Observer>();

    }

    // 调用接入方的update更新数据
    public void dateChange() {
        notifyObserver();

    }

    // 当数据有更新时, 就调用setData();
    public void setData(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        dateChange();

    }

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);

    }

    @Override
    public void removeObserver(Observer observer) {
        if (observers.contains(observer)) {
            observers.remove(observer);

        }

    }

    // 通知 即遍历所有的观察者
    @Override
    public void notifyObserver() {
        for (int i = 0; i < observers.size(); i++) {
            observers.get(i).update(this.temperature, this.pressure, this.humidity);

        }

    }
}

3.Observer

package com.pattern.设计模式.观察者模式;

// 观察者接口 由观察者来实现
public interface Observer {

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

4.CurrentConditions

package com.pattern.设计模式.观察者模式;

import org.omg.CORBA.Object;

public class CurrentConditions implements Observer {

    private float temperature;
    private float pressure;
    private float humidity;

    public void update(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        disPlay();
    }

    private void disPlay() {
        System.out.println("温度:" + temperature);
        System.out.println("气压:" + pressure);
        System.out.println("湿度:" + humidity);
    }


}

5.Baidu

package com.pattern.设计模式.观察者模式;

public class Baidu implements Observer{
    private float temperature;
    private float pressure;
    private float humidity;

    @Override
    public void update(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        disPlay();
    }

    private void disPlay() {
        System.out.println(">>>>>>>>>>>>百度<<<<<<<<<<<<<<<");
        System.out.println("百度温度:" + temperature);
        System.out.println("百度气压:" + pressure);
        System.out.println("百度适度:" + humidity);
    }
}

6.Test

package com.pattern.设计模式.观察者模式;

public class Test {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();

        // 创建观察者
        CurrentConditions currentConditions = new CurrentConditions();
        // 创建一个新的观察者 百度
        Baidu baidu = new Baidu();

        // 将这个观察者注册进 WeatherData
        weatherData.registerObserver(currentConditions);
        // 将百度观察者加入
        weatherData.registerObserver(baidu);
        // 移除一个观察者
        weatherData.removeObserver(currentConditions);

        // 测试
        weatherData.setData(20.3f, 53.2f, 64.2f);

    }
}

4.中介者模式

4.1 中介者模式概述

(1)基本介绍

①中介者(Mediator)模式:用一个中介对象来封装一系列的对象交互,
	中介者是各个对象不需要显示的相互作用,从而使其耦合松散,而且
	可以独立的改变它们之间的交互

②中介者模式属于行为型模式,使代码易于维护

③比如MVC模式,C是M和V的中介者,在前后端交互中起到了中间人的作用

(2)原理类图
在这里插入图片描述
(3)代码类图
在这里插入图片描述

5. 备忘录模式

备忘录模式 等等

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值