java-访问者模式

        访问者模式是比较难理解的一种设计模式。。。  至少对我来说

        访问者模式的定义为:封装一些作用于某种 数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。

        我自己的访问者代码:

package InvolvedMode.visitor;

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

/**  
 *  VisitorTest : 访问者模式
 * @author xuejupo  [email protected] 
 * create in 2015-12-30 下午1:47:25    
 */

public class VisitorTest {

	/**  
	 * main: 
	 * @param args 
	 * void  返回类型   
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Men wangdachui = new Men();
		//王大锤想去家乐福
		wangdachui.addPublicAreas(new Carrefour());
		//王大锤想去夜店
		wangdachui.addPublicAreas(new Club());
		//王大锤逛自己的公共场所
		wangdachui.display();
	}
}

/**  
* goods: 一个商品接口
* @author xuejupo  [email protected] 
* create in 2015-12-30 下午1:52:16  
*    
*/
interface goods{
}

/**  
* apple: 苹果是商品,只有price属性
* @author xuejupo  [email protected] 
* create in 2015-12-30 下午1:55:46  
*    
*/
class Apple implements goods{
	double price;
}
/**  
* orange:橘子也是商品
* @author xuejupo  [email protected] 
* create in 2015-12-30 下午1:56:19  
*    
*/
class Orange implements goods{
	double price;
}

/**  
* publicAreas: 公共场所统一接口
* @author xuejupo  [email protected] 
* create in 2015-12-30 下午2:15:21  
*    
*/
interface PublicAreas{
	/**  
	* accept: 所有的公共场所都要接待来访者
	* @param vistor 
	* void  返回类型   
	*/
	void accept(IVistor vistor);
}

/**  
* market: 商场接口
* @author xuejupo  [email protected] 
* create in 2015-12-30 下午1:59:03  
*    
*/
interface Market extends PublicAreas{
	/**
	* sellApple:  商场可以卖苹果
	* void  返回类型
	 */
	void sellApple();
	/**  
	* sellOrange:  商场也可以卖橘子
	* void  返回类型   
	*/
	void sellOrange();
	
}
/**  
* Carrefour: 家乐福商场
* @author xuejupo  [email protected] 
* create in 2015-12-30 下午2:01:10  
*    
*/
class Carrefour implements Market{
	//家乐福的商品
	private goods apple = new Apple();
	private goods orange = new Orange();
	@Override
	public void sellApple() {
		// TODO Auto-generated method stub
		System.out.println("我卖苹果,新鲜");
	}
	@Override
	public void sellOrange() {
		// TODO Auto-generated method stub
		System.out.println("我卖橘子,新鲜");
	}
	@Override
	public void accept(IVistor vistor) {
		// TODO Auto-generated method stub
		vistor.visit(this);
	}
}
/**  
* Club:  夜店,也算一个公共场所
* @author xuejupo  [email protected] 
* create in 2015-12-30 下午2:16:32  
*    
*/
class Club implements PublicAreas{
	/**  
	* hasGirl:  男人去夜店关心什么?    有没有美女
	* void  返回类型   
	*/
	public void hasGirl(){
		System.out.println("这里只有芙蓉,玉凤!");
	}
	@Override
	public void accept(IVistor vistor) {
		// TODO Auto-generated method stub
		vistor.visit(this);
	}
	
}


/**  
* IVistor:访问者接口
* @author xuejupo  [email protected] 
* create in 2015-12-30 下午2:12:06  
*    
*/
interface IVistor{
	void visit(Carrefour carrefour);
	void visit(Club club);
}

/**  
* Vostor: 访问者
* @author xuejupo  [email protected] 
* create in 2016-1-5 下午7:10:50  
*    
*/
class Vistor implements IVistor{
	/**
	 * 去超市,关心的是有没有苹果卖
	 */
	public void visit(Carrefour carrefour) {
		// TODO Auto-generated method stub
		carrefour.sellOrange();
	}
	/**
	 * 去夜店,关心的是有没有美女
	 */
	public void visit(Club club) {
		// TODO Auto-generated method stub
		club.hasGirl();
	}
}
/**  
* people: 人类接口
* @author xuejupo  [email protected] 
* create in 2015-12-30 下午2:22:50  
*    
*/
interface people{
}
class Men implements people{
	//每个男人都有自己想去的公共场所
	private List<PublicAreas> l;
	private IVistor vistor = new Vistor();
	public Men(){
		l = new ArrayList<PublicAreas>();
	}
	/**  
	* setVistor: 设置访问者对象
	* @param vistor 
	* void  返回类型   
	*/
	public void setVistor(IVistor vistor){
		this.vistor = vistor;
	}
	/**  
	* addPublicAreas: 增加自己想去的公共场所
	* @param p 
	* void  返回类型   
	*/
	public void addPublicAreas(PublicAreas p){
		this.l.add(p);
	}
	/**  
	* display:  去自己想去的公共场所逛逛
	* void  返回类型   
	*/
	public void display(){
		for(PublicAreas p:l){
			p.accept(vistor);
		}
	}
}



 结果:

我卖橘子,新鲜
这里只有芙蓉,玉凤!

      个人想法:

        设计模式之禅上的例子是最适合于访问者模式了。首先,他的数据结构基本已经定了,数据结构基本就那么几种,包含元素也已经上线稳定。但是在数据结构稳定的前提下,对数据结构的操作还有修改和扩展,这种形式比较适合用访问者模式。

       比如上面的代码,假设数据结构已经稳定了,超市只卖橘子,夜店只有玉凤和芙蓉,那么如果王大锤突然变重口(变更数据结构的操作)想去夜店找玉凤,那么只需增加一个访问者类:

class Vistor implements IVistor{
	/**
	 * 去夜店,找玉凤
	 */
	public void visit(Club club) {
		// TODO Auto-generated method stub
                System.out.println("玉凤看起来很美~~~");
		club.getGirl();
	}
}

   然后调用王大锤的set方法即可,不需要修改现有类,这是比较好的方式。

         但是。。。。    这里有两个设定,一是现有数据结构基本不变并且针对数据结构的操作可能会有变更;二是项目在设计之初就已经用了访问者模式了(这点比较难)。。   因为数据结构稳定就意味着项目已经设计编码基本完毕,如果项目设计之初没有使用访问者模式,那要用它可能就要修改所有代码。。。  这显然是很2的。。。  而项目设计之初就用他。。。 感觉也有点22的。。。。    总觉得这个模式很鸡肋。。   如果有什么不对的,希望大神能留言提点

猜你喜欢

转载自709002341.iteye.com/blog/2268756