前言
目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~
本节给大家讲一下设计模式中的访问者模式,并结合实际业务场景给大家讲解如何使用~
本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~
题外
上周二阳了,所以拖更了一会,简单说一下症状吧,有的小伙伴可能没经历过,总的来讲症状较第一次比较轻,我没有出现发烧的症状。主要表现为鼻塞,咽喉疼痛,期间也没有使用过任何药物,完全自愈,所以大家也不用太担心自己阳了之后会不会和第一次一样,平时外出口罩还是要带好的,毕竟阳了之后喉咙还是有点不舒服的,从发现到症状消失大概花了一个礼拜左右,准确转阴的时间在3天左右。
访问者模式
访问者模式是一种行为型设计模式,它定义了一种将算法与它们的对象结构分离的方式。通过这种方式,算法可以在不改变对象结构的情况下独立于对象结构的类访问对象。这种模式是使用访问者和元素对象的多态行为来实现的。
public interface Visitor {
void visit(Element element);
}
public interface Element {
void accept(Visitor visitor);
String operation();
}
public class ConcreteVisitor implements Visitor {
public void visit(Element element) {
System.out.println("Visiting " + element.operation());
}
}
public class ConcreteElement implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String operation() {
return "ConcreteElement";
}
}
public class Client {
public static void main(String[] args) {
Element element = new ConcreteElement();
Visitor visitor = new ConcreteVisitor();
element.accept(visitor);
// Visiting ConcreteElement
}
}
在这个示例中,我们有三个接口: Visitor , Element 和它们的具体实现类。 Visitor 接口定义了 visit() 方法,该方法接受一个 Element 对象,然后访问该对象。 Element 接口定义了 accept() 方法,该方法接受一个 Visitor 对象,然后将自身作为参数传递给该对象。 ConcreteElement 是一个具体的 Element 实现,它重写了 accept() 方法来调用 Visitor 对象的 visit() 方法。 ConcreteVisitor 是一个具体的 Visitor 实现,它实现了 visit() 方法,对于每个传递给它的元素对象,它都将打印一条消息。在 Client 类中,我们创建了一个 ConcreteElement对象,然后创建了一个ConcreteVisitor 对象,并调用 accept() 方法来访问元素对象。当调用 accept() 方法时,元素对象会将自身作为参数传递给Visitor对象的visit()方法。
总的来说,访问者模式允许我们在不更改结构的情况下,访问一个对象的元素。这使得我们可以定义一个新的操作(即访问者),并使用该操作来访问现有元素,而无需更改现有元素的结构。
最佳实践
电商平台应用中,访问者模式可以用于对购物车中的商品进行不同的操作,例如计算购物车中的总价、修改购物车中的商品数量等。
首先,我们定义一个购物车中的商品类 CartItem 和一个购物车类 ShoppingCart ,它包含一个 List 类型的 items 属性,存储购物车中的商品信息。CartItem 类实现了 Element 接口,通过实现 accept() 方法来接受一个 Visitor(计算总价或修改数量) 对象的访问。ShoppingCart 类实现了 Visitor 接口,通过实现 visit() 方法来访问购物车中的商品。
// 访问购物车的 Visitor 接口
public interface Visitor {
void visit(CartItem cartItem);
}
// Element 接口表明该类可以接受访问者
public interface Element {
void accept(Visitor visitor);
}
// ShoppingCart 类是一个 Visitor,用于访问购物车中的商品
public class ShoppingCart implements Visitor {
private List<CartItem> items = new ArrayList<CartItem>();
public void addItem(CartItem item) {
items.add(item);
}
public void removeItem(CartItem item) {
items.remove(item);
}
public void visit(CartItem item) {
// 计算购物车中商品的总价
System.out.println("Visiting " + item.getName());
}
public double calculateTotalPrice() {
double totalPrice = 0;
for (CartItem item : items) {
item.accept(this);
totalPrice += item.getPrice() * item.getQuantity();
}
return totalPrice;
}
}
// 购物车中的商品类,实现了 Element 接口
public class CartItem implements Element {
private String name;
private double price;
private int quantity;
public CartItem(String name, double price, int quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public int getQuantity() {
return quantity;
}
}
// 测试
public class Client {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
cart.addItem(new CartItem("item1", 10.00, 2));
cart.addItem(new CartItem("item2", 20.00, 1));
cart.addItem(new CartItem("item3", 30.00, 3));
double totalPrice = cart.calculateTotalPrice();
System.out.println("Total price: " + totalPrice);
// Visiting item1
// Visiting item2
// Visiting item3
// Total price: 130.0
}
}
我们通过在 CartItem 类中实现 accept() 方法来接受 Visitor 对象的访问。然后,我们在 ShoppingCart 类中实现 visit() 方法来访问购物车中的商品。在 calculateTotalPrice() 方法中,我们遍历购物车中的商品并调用 accept() 方法来访问购物车中的每个商品。在访问每个商品时, ShoppingCart 类计算商品的总价。运行测试代码后,我们可以看到输出结果为 Total price: 110.0 ,这是购物车中商品的总价。
总的来说,使用访问者模式可以帮助我们在不改变商品或购物车类的情况下,实现对购物车中的商品进行不同的操作。这样可以使购物车类更加灵活和可扩展。
结束语
设计模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。下节给大家讲依赖注入模式~
本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注鼓励一下呗~
相关文章
- 一起来学设计模式之认识设计模式
- 一起来学设计模式之单例模式
- 一起来学设计模式之工厂模式
- 一起来学设计模式之建造者模式
- 一起来学设计模式之原型模式
- 一起来学设计模式之适配器模式
- 一起来学设计模式之桥接模式
- 一起来学设计模式之组合模式
- 一起来学设计模式之装饰器模式
- 一起来学设计模式之外观模式
- 一起来学设计模式之享元模式
- 一起来学设计模式之代理模式
- 一起来学设计模式之责任链模式
- 一起来学设计模式之命令模式
- 一起来学设计模式之解释器模式
- 一起来学设计模式之迭代器模式
- 一起来学设计模式之中介者模式
- 一起来学设计模式之备忘录模式
- 一起来学设计模式之观察者模式
- 一起来学设计模式之状态模式
- 一起来学设计模式之策略模式
- 一起来学设计模式之模板方法模式
项目源码(源码已更新 欢迎star⭐️)
Kafka 专题学习
- 一起来学kafka之Kafka集群搭建
- 一起来学kafka之整合SpringBoot基本使用
- 一起来学kafka之整合SpringBoot深入使用(一)
- 一起来学kafka之整合SpringBoot深入使用(二)
- 一起来学kafka之整合SpringBoot深入使用(三)
项目源码(源码已更新 欢迎star⭐️)
ElasticSearch 专题学习
项目源码(源码已更新 欢迎star⭐️)
往期并发编程内容推荐
- Java多线程专题之线程与进程概述
- Java多线程专题之线程类和接口入门
- Java多线程专题之进阶学习Thread(含源码分析)
- Java多线程专题之Callable、Future与FutureTask(含源码分析)
- 面试官: 有了解过线程组和线程优先级吗
- 面试官: 说一下线程的生命周期过程
- 面试官: 说一下线程间的通信
- 面试官: 说一下Java的共享内存模型
- 面试官: 有了解过指令重排吗,什么是happens-before
- 面试官: 有了解过volatile关键字吗 说说看
- 面试官: 有了解过Synchronized吗 说说看
- Java多线程专题之Lock锁的使用
- 面试官: 有了解过ReentrantLock的底层实现吗?说说看
- 面试官: 有了解过CAS和原子操作吗?说说看
- Java多线程专题之线程池的基本使用
- 面试官: 有了解过线程池的工作原理吗?说说看
- 面试官: 线程池是如何做到线程复用的?有了解过吗,说说看
- 面试官: 阻塞队列有了解过吗?说说看
- 面试官: 阻塞队列的底层实现有了解过吗? 说说看
- 面试官: 同步容器和并发容器有用过吗? 说说看
- 面试官: CopyOnWrite容器有了解过吗? 说说看
- 面试官: Semaphore在项目中有使用过吗?说说看(源码剖析)
- 面试官: Exchanger在项目中有使用过吗?说说看(源码剖析)
- 面试官: CountDownLatch有了解过吗?说说看(源码剖析)
- 面试官: CyclicBarrier有了解过吗?说说看(源码剖析)
- 面试官: Phaser有了解过吗?说说看
- 面试官: Fork/Join 有了解过吗?说说看(含源码分析)
- 面试官: Stream并行流有了解过吗?说说看