设计意图
- 访问者模式:主要用于分离数据结构和对数据结构中元素的操作。使得新增对数据结构元素的操作变得容易,而不需要修改数据结构本身。例如,一个由多种图形(如圆形、矩形)组成的图形结构,当需要新增计算图形面积、周长等不同操作时,使用访问者模式可在不修改图形类的前提下实现。
// 抽象元素类
abstract class Element {
public abstract void accept(Visitor visitor);
}
// 具体元素类1
class Circle extends Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
// 具体元素类2
class Rectangle extends Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
// 抽象访问者
interface Visitor {
void visit(Circle circle);
void visit(Rectangle rectangle);
}
// 具体访问者1,计算面积
class AreaVisitor implements Visitor {
@Override
public void visit(Circle circle) {
// 计算圆形面积逻辑
}
@Override
public void visit(Rectangle rectangle) {
// 计算矩形面积逻辑
}
}
- 策略模式:定义一系列算法,将每个算法封装起来,并使它们可以相互替换。其目的是让算法的变化独立于使用算法的客户。比如,一个支付系统,有多种支付方式(如微信支付、支付宝支付),每种支付方式就是一个具体策略。
// 抽象策略
interface PaymentStrategy {
void pay(double amount);
}
// 具体策略1,微信支付
class WeChatPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("使用微信支付:" + amount);
}
}
// 具体策略2,支付宝支付
class AlipayPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("使用支付宝支付:" + amount);
}
}
// 上下文
class ShoppingCart {
private PaymentStrategy paymentStrategy;
public ShoppingCart(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void pay(double amount) {
paymentStrategy.pay(amount);
}
}
- 观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。例如,新闻发布系统,当有新新闻发布时,所有订阅该新闻的用户会收到通知。
// 抽象主题
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 具体主题
class NewsPublisher implements Subject {
private List<Observer> observers = new ArrayList<>();
private String news;
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(news);
}
}
public void publishNews(String news) {
this.news = news;
notifyObservers();
}
}
// 抽象观察者
interface Observer {
void update(String news);
}
// 具体观察者,用户
class User implements Observer {
private String name;
public User(String name) {
this.name = name;
}
@Override
public void update(String news) {
System.out.println(name + " 收到新闻:" + news);
}
}
结构特点
- 访问者模式:包含抽象元素、具体元素、抽象访问者和具体访问者。元素类有接受访问者的方法,访问者类有针对不同元素的访问方法。元素结构和操作解耦。
- 策略模式:由抽象策略、具体策略和上下文组成。上下文持有一个抽象策略的引用,通过组合方式使用具体策略。强调算法的可替换性。
- 观察者模式:有抽象主题、具体主题、抽象观察者和具体观察者。主题维护观察者列表,通过通知方法告知观察者状态变化。重点在于对象间的依赖关系。
适用场景
- 访问者模式:适用于数据结构相对稳定,但对数据结构中元素的操作经常变化的场景。例如编译器的语义分析阶段,语法树结构稳定,但不同的语义检查操作可以通过访问者模式实现。
- 策略模式:当有多种算法变体,并且希望在运行时根据不同情况选择不同算法时使用。比如电商系统中不同促销策略的选择。
- 观察者模式:用于当一个对象状态改变需要通知多个其他对象,并且这些对象对该状态改变做出响应的场景。如消息推送系统、股票价格监控系统等。