Java设计模式Ⅶ
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)代码类图