Java设计模式--访问者模式

本文深入解析访问者模式,探讨其定义、适用场景、优缺点,并通过购物车示例展示其实现方式。访问者模式允许在不修改现有类库的情况下定义新操作,适用于对象结构包含多种类型对象且需频繁定义新操作的场景。

一、简介

1.1 模式定义

表示一个作用于某个对象结构中某个元素的操作,它使我们可以在不改变某个元素的类的前提下定义作用于这些元素的新操作。访问者模式是一种行为型模式。

1.2 适用场景

1)一个对象结构包含很多类型的对象,希望对这些对象实施一些依赖其具体类型的操作。在访问者中针对每一种具体的类型都提供了一个访问操作,不同类型的对象可以有不同的访问操作。
2)需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让给这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。访问者模式使得我们可以将相关的访问操作集中起来定义访问者类中,对象结构可以被多个不同的访问者类所使用,将对象本身与对象的访问操作分离。
3)对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。

1.3 优点

1)使得增加新的访问操作变得很容易。使用访问者模式,增加新的访问操作就意味着增加一个新的访问者类,无须修改现有类库代码,符合“开闭原则”的要求。
2)将有关元素对象的访问行为集中到一个访问者对象中,而不是分散到一个个的元素类中。类的职责更加清晰,有利于对象结构中元素对象的复用,相同的对象结构可以供多个不同的访问者访问。
3)可以跨过类的等级结构访问属于不同的等级结构的元素类。
4)让用户能够在不修改现有类层次结构的情况下,定义该类层次结构的新操作。

1.4 缺点

1)增加新的元素类很困难。在访问者模式中,每增加一个新的元素类都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作,违背了“开闭原则”的要求。
2)破坏封装。访问者模式要求访问者对象访问并调用没一个元素对象的操作,这意味着元素对象有时候必须暴露一些自己的内部操作和内部状态,否则无法提供访问者访问。

二、示例:购物车

2.1 结构图

在这里插入图片描述

2.2 抽象访问者Visitor(访问者类)
public abstract class Visitor {

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

	public abstract void visit(Apple apple);
	
	public abstract void visit(Book book);
	
}
2.3 具体访问者Customer(顾客类)
public class Customer extends Visitor{

	@Override
	public void visit(Apple apple) {
		System.out.println("顾客" + name + "选择苹果。");
	}

	@Override
	public void visit(Book book) {
		System.out.println("顾客" + name + "买书。");
	}

}

2.4 具体访问者类Saler(收银员类)
public class Saler extends Visitor{

	@Override
	public void visit(Apple apple) {
		System.out.println("收银员" + name + "给苹果过秤,然后计算价格。");
	}

	@Override
	public void visit(Book book) {
		System.out.println("收银员" + name + "直接计算书的价格");
	}

}
2.5 抽象元素类Product(商品类)
public interface Product {
	
	public void accept(Visitor visitor);
	
}

2.6 具体元素类Apple(苹果类)
public class Apple implements Product{

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

}

2.7 具体元素类Book(书籍类)
public class Book implements Product{

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

}

2.8 对象结构BuyBasket(购物车类)
public class BuyBasket {
	
	private List<Product> list = new ArrayList<>();
	
	public void accept(Visitor visitor) {
		Iterator<Product> i = list.iterator();
		while(i.hasNext()) {
			i.next().accept(visitor);
		}
	}
	
	public void add(Product product) {
		list.add(product);
	}

	public void remove(Product product) {
		list.remove(product);
	}
	
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书香水墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值