二十五、访问者模式

1、什么是访问者模式

  • Visitor模式也叫访问者模式,是行为模式之一,它分离对象的数据和行为,使用Visitor模式,可以不修改已有类的情况下,增加新的操作。

2、访问者模式的应用示例

  • 比如有一个公园,有一到多个不同的组成部分;该公园存在多个访问者:清洁工A负责打扫公园的A部分,清洁工B负责打扫公园的B部分,公园的管理者负责检点各项事务是否完成,上级领导可以视察公园等等。也就是说,对于同一个公园,不同的访问者有不同的行为操作,而且访问者的种类也可能需要根据时间的推移而变化(行为的扩展性)。
  • 根据软件设计的开闭原则(对修改关闭,对扩展开放),我们怎么样实现这种需求呢?

3、访问者模式的结构

在这里插入图片描述

4、访问者模式的角色和职责

  • 1)访问者角色(Visitor):
    • 为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。这样访问者就可以通过该元素角色的特定接口直接访问它。
  • 2)具体访问者角色(Concrete Visitor):
    • 实现每个由访问者角色(Visitor)声明的操作。
  • 3)元素角色(Element):
    • 定义一个Accept操作,它以一个访问者为参数。
  • 4)具体元素角色(Concrete Element):
    • 实现由元素角色提供的Accept操作。
  • 5)对象结构角色(Object Structure):
    • 这是使用访问者模式必备的角色。它要具备以下特征:能枚举它的元素;可以提供一个高层的接口以允许该访问者访问它的元素;可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序集合。

5、代码实现

package com.example.demo01;

/**
 * 访问者
 * @author Guardian
 *
 */
public interface Visitor {

	public void visit(Park park);
	public void visit(ParkA parkA);
	public void visit(ParkB parkB);
}
package com.example.demo01;

/**
 * 清洁工A,负责parkA的卫生情况
 * @author Guardian
 *
 */
public class VisitorA implements Visitor{

	@Override
	public void visit(Park park) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visit(ParkA parkA) {
		System.out.println("清洁工A:完成公园"+parkA.getName()+"的卫生");
	}

	@Override
	public void visit(ParkB parkB) {
		// TODO Auto-generated method stub
		
	}

}
package com.example.demo01;

/**
 * 清洁工B,负责parkB的卫生情况
 * @author Guardian
 *
 */
public class VisitorB implements Visitor{

	@Override
	public void visit(Park park) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void visit(ParkA parkA) {
	}

	@Override
	public void visit(ParkB parkB) {
		System.out.println("清洁工B:完成公园"+parkB.getName()+"的卫生");
	}

}
package com.example.demo01;


public class VisitorManager implements Visitor{

	@Override
	public void visit(Park park) {
		System.out.println("管理员:负责公园"+	park.getName() +"卫生检查");
	}

	@Override
	public void visit(ParkA parkA) {
		System.out.println("管理员:负责公园"+	parkA.getName() +"卫生检查");
	}

	@Override
	public void visit(ParkB parkB) {
		System.out.println("管理员:负责公园"+	parkB.getName() +"卫生检查");
	}

}
package com.example.demo01;

/**
 * 公园每一部分的抽象
 * @author Guardian
 *
 */
public interface ParkElement {

	//用来接纳访问者
	public void accept(Visitor visitor);
}
package com.example.demo01;

/**
 * 公园的A部分
 * @author Guardian
 *
 */
public class ParkA implements ParkElement {
	
	private String name;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	@Override
	public void accept(Visitor visitor) {
		visitor.visit(this);
	}

}
package com.example.demo01;

/**
 * 公园的B部分
 * @author Guardian
 *
 */
public class ParkB implements ParkElement {

	private String name;
	
	public String getName() {
		return name;
	}

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

	@Override
	public void accept(Visitor visitor) {
		visitor.visit(this);
	}

}
package com.example.demo01;


public class Park implements ParkElement {

	private String name;
	private ParkA parkA;
	private ParkB parkB;
	
	
	public String getName() {
		return name;
	}

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

	public Park() {
		this.parkA = new ParkA();
		this.parkB = new ParkB();
		parkA.setName("A");
		parkB.setName("B");
	}

	@Override
	public void accept(Visitor visitor) {
		visitor.visit(this);
		parkA.accept(visitor);
		parkB.accept(visitor);
	}

	
}
package com.example.demo01;

import org.junit.Test;

public class MainClass {

	@Test
	public void test01(){
		Park park = new Park();
		park.setName("越秀公园");
		VisitorA visitorA = new VisitorA();
		
		park.accept(visitorA);
		
		VisitorB visitorB = new VisitorB();
		park.accept(visitorB);
		
		VisitorManager visitorManager = new VisitorManager();
		park.accept(visitorManager);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

QQ719872578

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值