设计模式(23)--访问者模式

访问者模式,用来解决多个访问者访问多个不同元素的问题。访问者模式引入了访问者角色和被访问者角色,不同访问者访问元素的方式不同。

举个例子(该例子来源于 《C#设计模式》刘伟 胡志刚 阎朝坤):

公司员工分为全职员工和兼职员工(这里员工就是被访问者),公司有财务部结算工资,人力资源部计算工作时长(这里财务部和人力资源部为访问者),于是就有了不同访问者访问不同被访问者的情况。

访问者模式UML类图如图:


示例代码:

抽象访问者:

/*****
 * 抽象访问者,财务部和人力资源部类的父类
 * @author wjw
 *
 */
public abstract class Visitor {

	
	/*****
	 * 访问者访问被访问者,所以应该有访问方法,那到底是定义一个抽象方法访问抽象被访问者
	 * 还是为每个具体访问者定义一个访问方法?其实都行,为了系统结构清晰最好各自定义,这里我做实验,用了一个方法
	 * 
	 */
	public abstract void visitor(BeVisitored beVisitored);
}


财务部和人力资源部两个具体访问者:

/*****
 * 财务部访问者
 * @author wjw
 *
 */
public class CaiwuVisitor extends Visitor{

	@Override
	public void visitor(BeVisitored beVisitored) {
		// TODO Auto-generated method stub
		if(beVisitored instanceof All){
			All all = (All)beVisitored;
			//全职者被财务部访问
			System.out.println("全职被访问者:" + all.getName() + "本月工资为:" + all.getMoney() + "元!");
			
		}else if(beVisitored instanceof Part){
			Part part = (Part)beVisitored;
			System.out.println("兼职被访问者:" + part.getName() + "本月工资为:" + part.getMoney() + "元!");
		}else{
			System.out.println("这里不该你访问!");
		}
	}

}
/****
 * 人力资源访问类
 * @author wjw
 *
 */
public class RenliziyuanVisitor extends Visitor{

	@Override
	public void visitor(BeVisitored beVisitored) {
		// TODO Auto-generated method stub
		// TODO Auto-generated method stub
				if(beVisitored instanceof All){
					All all = (All)beVisitored;
					//全职者被财务部访问
					System.out.println("全职被访问者:" + all.getName() + "本月工作时长为:" + all.getTime() + "小时!");
					
				}else if(beVisitored instanceof Part){
					Part part = (Part)beVisitored;
					System.out.println("兼职被访问者:" + part.getName() + "本月工资为:" + part.getTime() + "小时!");
				}else{
					System.out.println("这里不该你访问!");
				}
	}

}


被访问者接口:


/*****
 * 被访问者接口,全职员工和兼职员工实现该接口
 * @author wjw
 *
 */
interface  BeVisitored {

	//被访问者自然是接受访问了
	void accept(Visitor visitor);
}

全职员工和兼职员工两个具体被访问者:


/*****
 * 全职员工
 * @author wjw
 *
 */
public class All implements BeVisitored{

	private String name;//姓名
	private int  time;//int时常
	private int money;//工资
	
	
	
	public  All(String name, int time, int money) {
		super();
		this.name = name;
		this.time = time;
		this.money = money;
	}



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



	public String getName() {
		return name;
	}



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



	public int getTime() {
		return time;
	}



	public void setTime(int time) {
		this.time = time;
	}



	public int getMoney() {
		return money;
	}



	public void setMoney(int money) {
		this.money = money;
	}

	
	
	
}



/****
 * 兼职员工类
 * @author wjw
 *
 */
public class Part implements BeVisitored{

	private String name;//姓名
	private int  time;//int时常
	private int money;//工资
	
	
	
	public Part(String name, int time, int money) {
		super();
		this.name = name;
		this.time = time;
		this.money = money;
	}



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



	public String getName() {
		return name;
	}



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



	public int getTime() {
		return time;
	}



	public void setTime(int time) {
		this.time = time;
	}



	public int getMoney() {
		return money;
	}



	public void setMoney(int money) {
		this.money = money;
	}

	
	
	
}



访问辅助类:


/****
 * 本类为“对象结构类”(这是一个专有名词,不必强要理解),也属于访问者模式一员,具有辅助访问功能:
 * 本类主要完成:将被访问者添加到集合中,便于访问者批量访问被访问者
 * @author wjw
 *
 */
public class EmployeeUtils {
	private List<BeVisitored> beVisitors = new ArrayList<BeVisitored>();

	/****
	 * 添加被访问者元素
	 */
	public void addBeVisitor(BeVisitored beVisitored){
		
		beVisitors.add(beVisitored);
	}
	/****
	 * 所有被访问者接受某特定访问者访问
	 */
	public void aaccept(Visitor visitor){
		Iterator<BeVisitored> iterator = beVisitors.iterator();
		while(iterator.hasNext()){
			BeVisitored	beVisitor = iterator.next();
			
			beVisitor.accept(visitor);
			
		}
		
	}
}

Main方法:

public class Main {

	
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		//new两个全职员工
		BeVisitored b1All = new All("王朕", 100, 5000);
		BeVisitored b2All = new All("王明明", 100, 5000);
		//new两个兼职员工
		BeVisitored b1Part = new Part("窦唯", 100, 5000);
		BeVisitored b2Part = new Part("朴树", 100, 5000);
		
		//将员工放到集合中
		EmployeeUtils eu = new EmployeeUtils();
		eu.addBeVisitor(b1All);
		eu.addBeVisitor(b2All);
		eu.addBeVisitor(b1Part);
		eu.addBeVisitor(b2Part);
		
		//反射new具体访问者,通过辅助类访问所有被访问者
		Class visitorClazz = Class.forName(ReadProperties.readProperties("visitor_name"));
		Visitor visitor = (Visitor)visitorClazz.newInstance();
		eu.aaccept(visitor);
	}
}

运行结果:

全职被访问者:王朕本月工作时长为:100小时!
全职被访问者:王明明本月工作时长为:100小时!
兼职被访问者:窦唯本月工资为:100小时!
兼职被访问者:朴树本月工资为:100小时!


示例代码说明:大多数说明都在类中注释了

访问者模式说明:访问者模式用来解决多个访问者访问多个被访问者的问题,所以,不同访问者面对不同被访问者有不同处理方式。而访问者模式恰恰用来解决这种问题。访问者模式如果扩展访问者容易扩展,但扩展被访问者需修改代码,这属于开闭原则倾斜行。


如有错误,欢迎指正

end



安装Docker安装插件,可以按照以下步骤进行操作: 1. 首先,安装Docker。可以按照官方文档提供的步骤进行安装,或者使用适合您操作系统的包管理器进行安装。 2. 安装Docker Compose插件。可以使用以下方法安装: 2.1 下载指定版本的docker-compose文件: curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose 2.2 赋予docker-compose文件执行权限: chmod +x /usr/local/bin/docker-compose 2.3 验证安装是否成功: docker-compose --version 3. 在安装插件之前,可以测试端口是否已被占用,以避免编排过程中出错。可以使用以下命令安装netstat并查看端口号是否被占用: yum -y install net-tools netstat -npl | grep 3306 现在,您已经安装Docker安装Docker Compose插件,可以继续进行其他操作,例如上传docker-compose.yml文件到服务器,并在服务器上安装MySQL容器。可以参考Docker的官方文档或其他资源来了解如何使用DockerDocker Compose进行容器的安装和配置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Docker安装docker-compose插件](https://blog.youkuaiyun.com/qq_50661854/article/details/124453329)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Docker安装MySQL docker安装mysql 完整详细教程](https://blog.youkuaiyun.com/qq_40739917/article/details/130891879)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值