表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
情人节到了,要给每个MM送一束鲜花和一张卡片,可是每个MM送的花都要针对她个人的特点,每张卡片也要根据个人的特点来挑,我一个人哪搞得清楚,还是找花店老板和礼品店老板做一下Visitor,让花店老板根据MM的特点选一束花,让礼品店老板也根据每个人特点选一张卡,这样就轻松多了;
访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变。访问者模式适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。访问者模式使得增加新的操作变的很容易,就是增加一个新的访问者类。访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。当使用访问者模式时,要将尽可能多的对象浏览逻辑放在访问者类中,而不是放到它的子类中。访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。
还是以产品的开发为例,
产品开发分为 硬件和软件两部分。
对应的有 HardwareProduct 和 SoftwareProduct 两个类, 但是现在需要提升原有类的功能, 但是又不想改动到原有的结构,所以就添加额外的“访问者” 来提升功能。
代码列表:
IVisitor.java - 访问者接口
HardwareProduct.java 具体访问者
IVisitable.java - 元素接口
HardwareProduct.java - 具体元素
SoftwareProduct.java - 具体元素
TestMain.java - 测试主类
package designptn.vistor;
public interface IVisitor {
public void visitSoftware(SoftwareProduct product);
public void visitHardware(HardwareProduct product);
}
package designptn.vistor;
import java.util.Collection;
import java.util.Iterator;
public class ConcreteVisitor implements IVisitor {
@Override
public void visitSoftware(SoftwareProduct product) {
// TODO Auto-generated method stub
System.out.println(product.getProductName());
}
@Override
public void visitHardware(HardwareProduct product) {
// TODO Auto-generated method stub
System.out.println(product.getProductName());
}
}
package designptn.vistor;
public interface IVisitable {
public void accept(IVisitor visitor);
}
/**
* @author oscar999
* @date 2013-7-17
* @version V1.0
*/
package designptn.vistor;
public class HardwareProduct implements IVisitable {
private String productName;
public HardwareProduct(String productName){
this.productName = productName;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
@Override
public void accept(IVisitor visitor) {
// TODO Auto-generated method stub
visitor.visitHardware(this);
}
}
/**
* @author oscar999
* @date 2013-7-17
* @version V1.0
*/
package designptn.vistor;
public class SoftwareProduct implements IVisitable {
private String productName;
public SoftwareProduct(String productName){
this.productName = productName;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
@Override
public void accept(IVisitor visitor) {
// TODO Auto-generated method stub
visitor.visitSoftware(this);
}
}
package designptn.vistor;
public class TestMain {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
IVisitor visitor = new ConcreteVisitor();
HardwareProduct hardProduct = new HardwareProduct("hard 1");
hardProduct.accept(visitor);
SoftwareProduct softProduct = new SoftwareProduct("soft 1");
softProduct.accept(visitor);
}
}
修改ConcreteVisitor.java 和TestMain.java
package designptn.vistor;
import java.util.Iterator;
import java.util.List;
public class ConcreteVisitor implements IVisitor {
@SuppressWarnings("rawtypes")
public void visitProducts(List list) {
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instanceof IVisitable) {
((IVisitable) o).accept(this);
}
}
}
@Override
public void visitSoftware(SoftwareProduct product) {
// TODO Auto-generated method stub
System.out.println(product.getProductName());
}
@Override
public void visitHardware(HardwareProduct product) {
// TODO Auto-generated method stub
System.out.println(product.getProductName());
}
}
package designptn.vistor;
import java.util.ArrayList;
import java.util.List;
public class TestMain {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ConcreteVisitor visitor = new ConcreteVisitor();
HardwareProduct hardProduct = new HardwareProduct("hard 1");
hardProduct.accept(visitor);
SoftwareProduct softProduct = new SoftwareProduct("soft 1");
softProduct.accept(visitor);
System.out.println("--------------------------");
List list = new ArrayList();
list.add(new HardwareProduct("hard 2"));
list.add(new HardwareProduct("hard 3"));
list.add(new SoftwareProduct("soft 2"));
list.add(new SoftwareProduct("soft 3"));
visitor.visitProducts(list);
}
}