设计模式之访问者模式

一、定义:分装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

通过给每个基础类设置一个访问者,通过访问者可以访问到基础类的数据结构,然后访问者对这些基础类的数据结构定义一些新的操作,而不改变基础类的数据结构。

二、简单代码示例

基础类1 负责销售兵乒球

public class Object1 {
	private String name = "PingPongBall";
	private int price = 10;

	private static int stock = 100;

	private static int income = 0;

	public void sale(int num) {
		if (stock < num) {
			System.out.println("No enough stock");
			return;
		}
		stock -= num;
		income += num * price; //只有一个价格
	}

	public int reportIncome() {
		System.out.println("The income of sale " + name + " is " + income);
		return income;
	}

	public void accept(IVisitor visitor) {  //设置访问者
		visitor.visit(this);
	}
}
基础类2 负责销售篮球
public class Object2 {
	private String name = "basketball";
	private int outPrice = 100;

	private static int stock = 100;
	private static int inPrice = 50;
	private static int income = 0;

	public void sale(int num) {
		if (stock < num) {
			System.out.println("No enough stock");
			return;
		}
		stock -= num;
		income += num * (outPrice - inPrice); //分为进价 和销售价
	}

	public int reportIncome() {
		System.out.println("The income of sale " + name + " is " + income);
		return income;
	}

	public void accept(IVisitor visitor) {  //设置访问者
		visitor.visit(this);
	}
}
访问者类:

public interface IVisitor {      //设置访问者要访问的数据结构。 Object1 和 Object2 如果这两个对象是接口则更容易扩展
	int visit(Object1 obj1);

	int visit(Object2 obj2);

	void report();		//在访问各种数据结构后,定义的新操作。
}
具体访问者

public class Visitor implements IVisitor {

	private static int totalIncome = 0;

	@Override
	public int visit(Object1 obj1) {	//访问Object1的数据结构,并做新的操作。
		// TODO Auto-generated method stub
		totalIncome += obj1.reportIncome();
		return 0;
	}

	@Override
	public int visit(Object2 obj2) {	//访问Object2的数据结构,并做新的操作
		// TODO Auto-generated method stub
		totalIncome += obj2.reportIncome();
		return 0;
	}

	@Override
	public void report() {		//向调用者报告自己重新整理得到的新数据结构,可以用来做报表
		// TODO Auto-generated method stub
		System.out.println("Our Company's income of this year is:" + totalIncome);
	}

}
场景类:

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Object1 obj1 = new Object1();
		Object2 obj2 = new Object2();

		IVisitor visitor = new Visitor();

		// 基础类负责销售
		obj1.sale(2);
		obj1.sale(4);
		obj1.sale(10);
		obj2.sale(50);

		// 为每个基础类指定一个访问者,并通过访问者进行访问
		obj1.accept(visitor);
		obj2.accept(visitor);

		// 通过访问者访问所有的类,并提取所需要的数据 向调用者报告
		visitor.report();
	}

}
The income of sale PingPongBall is 160
The income of sale basketball is 2500
Our Company's income of this year is:2660
三、

优点:访问者模式符合职责单一原则,基础类负责单一的职责,如果要做总的报表分析活动,则交给访问者类去处理。访问者怎么变化,并不影响基础类和场景,十分容易扩展。访问者对数据结构的处理十分灵活,可以做更多的操作。
缺点:访问者模式访问者去访问一个类,就要求该类暴漏一些方法和数据结构,违反迪米特法则。访问者依赖于具体类,违反了依赖倒置原则,不面向接口编程使得扩展有点困难。




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值