设计模式----访问者模式UML和实现代码

1、什么是访问者模式?

访问者模式(Visitor)定义:表示一个做用于某对象结构中的各元素的操做。它使你能够在不改变现有各元素的类的前提下定义做用于这些元素的新操做。
java

类型:行为型模式(Behavioral)git

顺口溜: 中访策备迭 观模命状职解github

2、访问者模式UML

3、JAVA代码实现

package com.amosli.dp.behavior.visitor;

/**
 * VISITOR PATTERN
 * 
 * @author amosli
 *
 */
public class Client {
	public static void main(String[] args) {
		ObjectStructure obj = new ObjectStructure();
		obj.attach(new ConcreteElementA());
		obj.attach(new ConcreteElementB());

		obj.accept(new ConcreteVisitorA());
		obj.accept(new ConcreteVisitorB());

	}
}

package com.amosli.dp.behavior.visitor;

public abstract class Element {
	public abstract void accept(Visitor visitor);
}


package com.amosli.dp.behavior.visitor;

public abstract class Visitor {
	public abstract void visitConcreteElementA(ConcreteElementA elementA);
	public abstract void visitConcreteElementB(ConcreteElementB elementB);
}

package com.amosli.dp.behavior.visitor;

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

public class ObjectStructure {
	private List<Element> list = new ArrayList<Element>();

	public void attach(Element element) {
		list.add(element);
	}

	public void detach(Element element) {
		list.remove(element);
	}
	
	
	public void accept(Visitor visitor){
		for (Element element : list) {
			element.accept(visitor);
		}
	}

}


package com.amosli.dp.behavior.visitor;

public class ConcreteElementA extends Element {

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

	public void methodA() {
	}

}


package com.amosli.dp.behavior.visitor;

public class ConcreteElementB extends Element {

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

	public void methodB() {
	}

}

package com.amosli.dp.behavior.visitor;

public class ConcreteVisitorA extends Visitor {

	@Override
	public void visitConcreteElementA(ConcreteElementA elementA) {
		System.out.println(elementA.getClass().getName() + "被" + this.getClass().getName()+" 调用");
	}

	@Override
	public void visitConcreteElementB(ConcreteElementB elementB) {
		System.out.println(elementB.getClass().getName() + "被" + this.getClass().getName()+" 调用");
	}

}

package com.amosli.dp.behavior.visitor;

public class ConcreteVisitorB extends Visitor{

	@Override
	public void visitConcreteElementA(ConcreteElementA elementA) {
		System.out.println(elementA.getClass().getName() + "被" + this.getClass().getName()+" 调用");
	}

	@Override
	public void visitConcreteElementB(ConcreteElementB elementB) {
		System.out.println(elementB.getClass().getName() + "被" + this.getClass().getName()+" 调用");
	}

}


     根据对象的类型而对方法进行的选择,就是分派(Dispatch),分派(Dispatch)又分为两种,即静态分派动态分派shell

  静态分派(Static Dispatch)发生在编译时期,分派根据静态类型信息发生。静态分派对于咱们来讲并不陌生,方法重载就是静态分派。ide

  动态分派(Dynamic Dispatch)发生在运行时期,动态分派动态地置换掉某个方法。this

4、使用场景

一、 一个对象结构包含不少类对象,它们有不一样的接口,而你想对这些对象实施一些依赖于其具体类的操做。spa

二、 须要对一个对象结构中的对象进行不少不一样的而且不相关的操做,而你想避免让这些操做“污染”这些对象的类。Visitor模式使得你能够将相关的操做集中起来 定义在一个类中。code

三、 当该对象结构被不少应用共享时,用Visitor模式让每一个应用仅包含须要用到的操做。orm

四、定义对象结构的类不多改变,但常常须要在此结构上定义新的操做。改变对象结构类须要重定义对全部访问者的接口,这可能须要很大的代价。若是对象结构类常常改变,那么可能仍是在这些类中定义这些操做较好。对象

5、源码地址

本系列文章源码地址,https://github.com/amosli/dp  欢迎Fork  & Star !!

相关文章
相关标签/搜索