设计模式 —— 访问者模式

访问者模式

访问者模式的目的是封装一些施加于某种数据结构元素之上的操作,一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变。为不同类型的元素提供多种访问操作方式,且可以在不修改原有系统的情况下增加新的操作方式,这就是访问者模式的模式动机。
在这里插入图片描述案例:学校领导访问学生和教师

源代码:V1.0

package org.zangyu.Visitor;

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

public class Visitor {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        List<Person> listperson =new ArrayList<Person>();
        Person t1=new Teacher("张老师","编程原理",48);//老师
        Person t2=new Teacher("王老师","数据库",54);
        Person s1=new Student("赵同学","编程原理",90);//学生
        Person s2=new Student("刘同学","数据库",82);
        listperson.add(t1);listperson.add(t2);
        listperson.add(s1);listperson.add(s2);
        PresidentVisitor pv=new PresidentVisitor();//校长
        for(Person s:listperson)
        {
        	pv.Visit(s);
        }
        DeanVisitor dv=new DeanVisitor();//院长
        for(Person s:listperson) {
        	dv.Visit(s);
        }
	}

}

abstract class Person {
	private String name;

	public Person(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

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

}

class Teacher extends Person {// 教室

	private String course;// 所教课程
	private int amount;// 学时

	public Teacher(String name, String course, int amount) {
		super(name);
		this.course = course;
		this.amount = amount;
	}

	public String getCourse() {
		return course;
	}

	public void setCourse(String course) {
		this.course = course;
	}

	public int getAmount() {
		return amount;
	}

	public void setAmount(int amount) {
		this.amount = amount;
	}

}
class Student extends Person{
	private String course;//所学教程
	private int grade;//成绩
	public Student(String name, String course, int grade) {
		super(name);
		this.course = course;
		this.grade = grade;
	}
	public String getCourse() {
		return course;
	}
	public void setCourse(String course) {
		this.course = course;
	}
	public int getGrade() {
		return grade;
	}
	public void setGrade(int grade) {
		this.grade = grade;
	}
	
}
class PresidentVisitor{//校长访问
	public void Visit(Person person) {
		if(person instanceof Teacher) {
			Teacher teacher =(Teacher)person;
			System.out.println("校长访问老师"+teacher.getName()+"学时:"+teacher.getAmount());
		}else if(person instanceof Student) {
			Student student=(Student)person;
			System.out.println("校长访问学生"+student.getName()+"课程"+student.getCourse()+"成绩:"+student.getGrade());
		}
	}
}
class DeanVisitor{//院长访问
	public void Visit(Person person) {
		if(person instanceof Teacher) {
			Teacher teacher =(Teacher)person;
			System.out.println("院长访问老师"+teacher.getName()+"学时:"+teacher.getAmount());
		}else if(person instanceof Student) {
			Student student=(Student)person;
			System.out.println("院长访问学生"+student.getName()+"课程"+student.getCourse()+"成绩:"+student.getGrade());
		}
	}
}

PresidentVisitor和DeanVisitor都含有visit()方法,因此可以将其提取出来
源代码:V2.0

package org.zangyu.Visitor;

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

public class Visitor2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List<Person> listperson = new ArrayList<Person>();
		Person t1 = new Teacher("张老师", "编程原理", 48);// 老师
		Person t2 = new Teacher("王老师", "数据库", 54);
		Person s1 = new Student("赵同学", "编程原理", 90);// 学生
		Person s2 = new Student("刘同学", "数据库", 82);
		listperson.add(t1);
		listperson.add(t2);
		listperson.add(s1);
		listperson.add(s2);
		Visitor pv = new PresidentVisitor();// 校长
		for (Person s : listperson) {
			pv.visit(s);
		}
	    Visitor dv = new DeanVisitor();// 院长
		for (Person s : listperson) {
			dv.visit(s);
		}
	}

}

abstract class Person {
	private String name;

	public Person(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

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

}

class Teacher extends Person {// 教室

	private String course;// 所教课程
	private int amount;// 学时

	public Teacher(String name, String course, int amount) {
		super(name);
		this.course = course;
		this.amount = amount;
	}

	public String getCourse() {
		return course;
	}

	public void setCourse(String course) {
		this.course = course;
	}

	public int getAmount() {
		return amount;
	}

	public void setAmount(int amount) {
		this.amount = amount;
	}

}

class Student extends Person {
	private String course;// 所学教程
	private int grade;// 成绩

	public Student(String name, String course, int grade) {
		super(name);
		this.course = course;
		this.grade = grade;
	}

	public String getCourse() {
		return course;
	}

	public void setCourse(String course) {
		this.course = course;
	}

	public int getGrade() {
		return grade;
	}

	public void setGrade(int grade) {
		this.grade = grade;
	}

}

interface Visitor {
	abstract void visit(Person person);
}

class PresidentVisitor implements Visitor {// 校长访问

	@Override
	public void visit(Person person) {
		// TODO Auto-generated method stub
		if (person instanceof Teacher) {
			Teacher teacher = (Teacher) person;
			System.out.println("校长访问老师" + teacher.getName() + "学时:" + teacher.getAmount());
		} else if (person instanceof Student) {
			Student student = (Student) person;
			System.out.println("校长访问学生" + student.getName() + "课程" + student.getCourse() + "成绩:" + student.getGrade());
		}
	}
}

class DeanVisitor implements Visitor {// 院长访问

	@Override
	public void visit(Person person) {
		// TODO Auto-generated method stub
		if (person instanceof Teacher) {
			Teacher teacher = (Teacher) person;
			System.out.println("院长访问老师" + teacher.getName() + "学时:" + teacher.getAmount());
		} else if (person instanceof Student) {
			Student student = (Student) person;
			System.out.println("院长访问学生" + student.getName() + "课程" + student.getCourse() + "成绩:" + student.getGrade());
		}
	}

}

PresidentVisitor和DeanVisitor都含有visit()方法,因此可以将其提取出来将visit重载
源代码:V3.0

package org.zangyu.Visitor;

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

public class Visitor3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List<Person> listperson = new ArrayList<Person>();
		Person t1 = new Teacher("张老师", "编程原理", 48);// 老师
		Person t2 = new Teacher("王老师", "数据库", 54);
		Person s1 = new Student("赵同学", "编程原理", 90);// 学生
		Person s2 = new Student("刘同学", "数据库", 82);
		listperson.add(t1);
		listperson.add(t2);
		listperson.add(s1);
		listperson.add(s2);
		Visitor pv = new PresidentVisitor();// 校长
		for (Person s : listperson) {
			if (s instanceof Teacher) {
				Teacher teacher = (Teacher) s;
				pv.visit(teacher);
			} else if (s instanceof Student) {
				Student student = (Student) s;
				pv.visit(student);
			}
		}
		Visitor dv = new DeanVisitor();// 院长
		for (Person s : listperson) {
			if (s instanceof Teacher) {
				Teacher teacher = (Teacher) s;
				dv.visit(teacher);
			} else if (s instanceof Student) {
				Student student = (Student) s;
				dv.visit(student);
			}
		}
	}

}

abstract class Person {
	private String name;

	public Person(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

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

}

class Teacher extends Person {// 教室

	private String course;// 所教课程
	private int amount;// 学时

	public Teacher(String name, String course, int amount) {
		super(name);
		this.course = course;
		this.amount = amount;
	}

	public String getCourse() {
		return course;
	}

	public void setCourse(String course) {
		this.course = course;
	}

	public int getAmount() {
		return amount;
	}

	public void setAmount(int amount) {
		this.amount = amount;
	}

}

class Student extends Person {
	private String course;// 所学教程
	private int grade;// 成绩

	public Student(String name, String course, int grade) {
		super(name);
		this.course = course;
		this.grade = grade;
	}

	public String getCourse() {
		return course;
	}

	public void setCourse(String course) {
		this.course = course;
	}

	public int getGrade() {
		return grade;
	}

	public void setGrade(int grade) {
		this.grade = grade;
	}

}

interface Visitor {
	// 访问老师
	abstract void visit(Teacher teacher);

	// 访问学生
	abstract void visit(Student student);
}

class PresidentVisitor implements Visitor {// 校长访问

	@Override
	public void visit(Teacher teacher) {
		// TODO Auto-generated method stub
		System.out.println("校长访问老师" + teacher.getName() + "学时:" + teacher.getAmount());
	}

	@Override
	public void visit(Student student) {
		// TODO Auto-generated method stub

		System.out.println("校长访问学生" + student.getName() + "课程" + student.getCourse() + "成绩:" + student.getGrade());

	}
}

class DeanVisitor implements Visitor {// 院长访问

	@Override
	public void visit(Teacher teacher) {
		// TODO Auto-generated method stub
		System.out.println("院长访问老师" + teacher.getName() + "学时:" + teacher.getAmount());
	}

	@Override
	public void visit(Student student) {
		// TODO Auto-generated method stub
		System.out.println("院长访问学生" + student.getName() + "课程" + student.getCourse() + "成绩:" + student.getGrade());
	}

}

访问角色增加一个接收访问者的方法
源代码:V4.0

package org.zangyu.Visitor;

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

public class Visitor4 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List<Person> listperson = new ArrayList<Person>();
		Person t1 = new Teacher("张老师", "编程原理", 48);// 老师
		Person t2 = new Teacher("王老师", "数据库", 54);
		Person s1 = new Student("赵同学", "编程原理", 90);// 学生
		Person s2 = new Student("刘同学", "数据库", 82);
		listperson.add(t1);
		listperson.add(t2);
		listperson.add(s1);
		listperson.add(s2);
		Visitor pv = new PresidentVisitor();// 校长
		for (Person s : listperson) {
		 s.accept(pv);
		}
		Visitor dv = new DeanVisitor();// 院长
		for (Person s : listperson) {
			s.accept(dv);
		}
	}

}

abstract class Person {
	private String name;

	public Person(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

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

}

class Teacher extends Person {// 教室

	private String course;// 所教课程
	private int amount;// 学时

	public Teacher(String name, String course, int amount) {
		super(name);
		this.course = course;
		this.amount = amount;
	}

	public String getCourse() {
		return course;
	}

	public void setCourse(String course) {
		this.course = course;
	}

	public int getAmount() {
		return amount;
	}

	public void setAmount(int amount) {
		this.amount = amount;
	}

	@Override
	public void accept(Visitor visitor) {
		// TODO Auto-generated method stub
		visitor.visit(this);
	}

}

class Student extends Person {
	private String course;// 所学教程
	private int grade;// 成绩

	public Student(String name, String course, int grade) {
		super(name);
		this.course = course;
		this.grade = grade;
	}

	public String getCourse() {
		return course;
	}

	public void setCourse(String course) {
		this.course = course;
	}

	public int getGrade() {
		return grade;
	}

	public void setGrade(int grade) {
		this.grade = grade;
	}

	@Override
	public void accept(Visitor visitor) {
		// TODO Auto-generated method stub
		visitor.visit(this);
	}

}

interface Visitor {
	// 访问老师
	abstract void visit(Teacher teacher);

	// 访问学生
	abstract void visit(Student student);
}

class PresidentVisitor implements Visitor {// 校长访问

	@Override
	public void visit(Teacher teacher) {
		// TODO Auto-generated method stub
		System.out.println("校长访问老师" + teacher.getName() + "学时:" + teacher.getAmount());
	}

	@Override
	public void visit(Student student) {
		// TODO Auto-generated method stub

		System.out.println("校长访问学生" + student.getName() + "课程" + student.getCourse() + "成绩:" + student.getGrade());

	}
}

class DeanVisitor implements Visitor {// 院长访问

	@Override
	public void visit(Teacher teacher) {
		// TODO Auto-generated method stub
		System.out.println("院长访问老师" + teacher.getName() + "学时:" + teacher.getAmount());
	}

	@Override
	public void visit(Student student) {
		// TODO Auto-generated method stub
		System.out.println("院长访问学生" + student.getName() + "课程" + student.getCourse() + "成绩:" + student.getGrade());
	}

}

ObjeactList简化对象列表
源代码:V5.0

package org.zangyu.Visitor;

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

public class Visitor4 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Person t1 = new Teacher("张老师", "编程原理", 48);// 老师
		Person t2 = new Teacher("王老师", "数据库", 54);
		Person s1 = new Student("赵同学", "编程原理", 90);// 学生
		Person s2 = new Student("刘同学", "数据库", 82);

		ObjeactList list = new ObjeactList();
		list.Attach(s1);
		list.Attach(s2);
		list.Attach(t1);
		list.Attach(t2);
		Visitor pv = new PresidentVisitor();// 校长
		Visitor dv = new DeanVisitor();// 院长
		list.Display(pv);
		System.out.println("-------------------------");
		list.Display(dv);

	}
}

abstract class Person {
	private String name;

	public Person(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

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

	public abstract void accept(Visitor visitor);

}

class ObjeactList {
	List<Person> listperson = new ArrayList<Person>();

	public void Attach(Person element)// 增加
	{
		listperson.add(element);
	}

	public void Detach(Person element)// 移除
	{
		listperson.remove(element);
	}

	public void Display(Visitor visitor) {// 显示
		for (Person s : listperson) {
			s.accept(visitor);
		}
	}
}

class Teacher extends Person {// 教室

	private String course;// 所教课程
	private int amount;// 学时

	public Teacher(String name, String course, int amount) {
		super(name);
		this.course = course;
		this.amount = amount;
	}

	public String getCourse() {
		return course;
	}

	public void setCourse(String course) {
		this.course = course;
	}

	public int getAmount() {
		return amount;
	}

	public void setAmount(int amount) {
		this.amount = amount;
	}

	@Override
	public void accept(Visitor visitor) {
		// TODO Auto-generated method stub
		visitor.visit(this);
	}

}

class Student extends Person {
	private String course;// 所学教程
	private int grade;// 成绩

	public Student(String name, String course, int grade) {
		super(name);
		this.course = course;
		this.grade = grade;
	}

	public String getCourse() {
		return course;
	}

	public void setCourse(String course) {
		this.course = course;
	}

	public int getGrade() {
		return grade;
	}

	public void setGrade(int grade) {
		this.grade = grade;
	}

	@Override
	public void accept(Visitor visitor) {
		// TODO Auto-generated method stub
		visitor.visit(this);
	}

}

interface Visitor {
	// 访问老师
	abstract void visit(Teacher teacher);

	// 访问学生
	abstract void visit(Student student);
}

class PresidentVisitor implements Visitor {// 校长访问

	@Override
	public void visit(Teacher teacher) {
		// TODO Auto-generated method stub
		System.out.println("校长访问老师" + teacher.getName() + "学时:" + teacher.getAmount());
	}

	@Override
	public void visit(Student student) {
		// TODO Auto-generated method stub

		System.out.println("校长访问学生" + student.getName() + "课程" + student.getCourse() + "成绩:" + student.getGrade());

	}
}

class DeanVisitor implements Visitor {// 院长访问

	@Override
	public void visit(Teacher teacher) {
		// TODO Auto-generated method stub
		System.out.println("院长访问老师" + teacher.getName() + "学时:" + teacher.getAmount());
	}

	@Override
	public void visit(Student student) {
		// TODO Auto-generated method stub
		System.out.println("院长访问学生" + student.getName() + "课程" + student.getCourse() + "成绩:" + student.getGrade());
	}

}

访问者模式基本框架按
源代码:V6.0

package org.zangyu.Visitor;

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

public class Visitor5 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ObjectStrucure obs=new ObjectStrucure();
		obs.Attach(new ConcreteElementA());
		obs.Attach(new ConcreteElementB());
		ConcreteVistor1 v1 =new ConcreteVistor1();
		ConcreteVistor2 v2=new ConcreteVistor2();
		obs.Accept(v1);
		System.out.println("--------------------");
		obs.Accept(v2);
	}

}
abstract class Visitor
{
	public abstract void VisitConcreteElementA(ConcreteElementA cea);
	public abstract void VisitConcreteElementB(ConcreteElementB ceb);
}
class ConcreteVistor1 extends Visitor{

	@Override
	public void VisitConcreteElementA(ConcreteElementA cea) {
		// TODO Auto-generated method stub
		System.out.println(cea.getClass().toString()+"被"+this.getClass().toString()+"访问");
	}

	@Override
	public void VisitConcreteElementB(ConcreteElementB ceb) {
		// TODO Auto-generated method stub
		System.out.println(ceb.getClass().toString()+"被"+this.getClass().toString()+"访问");	
	}
	
}
class ConcreteVistor2 extends Visitor{

	@Override
	public void VisitConcreteElementA(ConcreteElementA cea) {
		// TODO Auto-generated method stub
		System.out.println(cea.getClass().toString()+"被"+this.getClass().toString()+"访问");
	}

	@Override
	public void VisitConcreteElementB(ConcreteElementB ceb) {
		// TODO Auto-generated method stub
		System.out.println(ceb.getClass().toString()+"被"+this.getClass().toString()+"访问");	
	}
	
}
class ObjectStrucure
{
	private List<Element> eles=new ArrayList<Element>();
	public void Attach(Element element)
	{
		eles.add(element);
	}
	public void Detach(Element element)
	{
	eles.remove(element);
	}
	public void Accept(Visitor visitor)
	{
		for(Element s:eles)
		{
			s.Accept(visitor);
		}
	}
}
abstract class Element
{
	public abstract void Accept(Visitor visitor);
}
class ConcreteElementA extends Element
{

	@Override
	public void Accept(Visitor visitor) {
		// TODO Auto-generated method stub
		visitor.VisitConcreteElementA(this);
	}
	public void OperationA() {}
	
}
 class ConcreteElementB extends Element
{


	public void OperationB() {}

	@Override
	public void Accept(Visitor visitor) {
		// TODO Auto-generated method stub
		visitor.VisitConcreteElementB(this);
		
	}
}

访问者模式的应用

  1. 何时使用

    需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作“污染”这些对象的类时

  2. 方法

在被访问的类里面添加一个对外提供接待访问者的接口
  1. 优点
符合单一职责原则
优秀的扩展性
灵活性非常高
  1. 缺点
具体元素对访问者公布细节,也就是说访问者关注了其他类的内部细节,这是迪米特法则所不建议的
具体元素变更比较困难
违背了依赖倒转原则。访问者依赖的是具体元素,而不是抽象元素

  1. 使用场景
一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖与其具体类的操作,也就是用迭代器模式已经不能胜任的情景
需要对一个对结构中的对象进行很多不同并且不相关的操作,而你想避免让这些操作“污染”这些对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Yu_Nan___

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

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

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

打赏作者

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

抵扣说明:

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

余额充值