对于如下所示的序列图所描述的场景,最适合于采用的设计模式是 (问题1) ;该模式适用的场合是 (问题2) 。

访问者模式是行为型设计模式的一种,核心逻辑是将作用于对象结构内元素的操作,与元素本身实现分离,能在不修改元素类的前提下,为元素灵活新增各类操作。它包含五大核心角色:定义操作规范的抽象访问者、实现具体操作的具体访问者、声明接受访问逻辑的抽象元素、承载业务数据的具体元素,以及管理元素集合的对象结构。
该模式的典型适用场景是对象结构相对稳定,不会频繁新增或修改元素类,但需要经常为结构内的元素添加新的操作逻辑,比如固定数据模型需要新增多种统计、导出等差异化处理逻辑的场景。
需要注意与其他易混淆模式区分:策略模式聚焦单一行为的不同算法实现动态替换;状态模式核心是对象行为随自身内部状态变化而改变;观察者模式基于发布-订阅机制实现对象间的一对多通知,这些模式的核心目标与应用场景和访问者模式差异显著。
访问者模式的优势是能大幅提升操作逻辑的扩展性,新增操作仅需新增具体访问者类,符合开闭原则;但缺点也很突出,若对象结构需要调整(如新增元素类),所有访问者类都需同步修改,维护成本会急剧上升,因此仅适配元素结构稳定的业务场景。
本题考察的是访问者模式(Visitor Pattern)。
访问者模式的核心思想是:将作用于对象结构元素的操作分离出来,放入独立的访问者对象中,这样可以在不改变元素类的前提下,向这些类中添加新的操作。
- Cab Company Dispatcher(调度员)持有一个客户列表(对象结构)。
- Customer(客户)是列表中的具体元素,定义了AcceptAVisitor方法。
- Taxi(出租车)扮演Visitor(访问者),通过**VisitCustomer()访问客户,并执行Transport(Customer)**操作。
问题 1:
A选项 Visitor:符合题意,正确。
B选项 Strategy:用于算法族的切换,不符合题意。
C选项 Observer:用于对象间的一对多通知,不符合题意。
D选项 State:用于对象状态驱动行为变化,不符合题意。
问题 2:
A选项(状态模式):强调对象行为随状态变化而变化,不符合题意。
B选项(访问者模式):对象结构稳定(客户类不常变化),但需要对结构中的元素(客户)增加新的操作(不同的出租车服务),完全符合本题。
C选项(策略模式):强调算法的可替换性,与访问者场景不符。
D选项(观察者模式):强调发布-订阅通知机制,与本题场景无关。
例子如下:
// 访问者接口
interface Visitor {
void visit(Customer customer);
}
// 具体访问者:Taxi 出租车
class Taxi implements Visitor {
@Override
public void visit(Customer customer) {
System.out.println("Taxi is transporting customer: " + customer.getName());
}
}
// 元素接口
interface Element {
void accept(Visitor visitor);
}
// 具体元素:Customer
class Customer implements Element {
private String name;
public Customer(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void accept(Visitor visitor) {
// 把自己交给访问者处理
visitor.visit(this);
}
}
// 对象结构:CabCompanyDispatcher
class CabCompanyDispatcher {
private List<Customer> customers = new ArrayList<>();
public void addCustomer(Customer customer) {
customers.add(customer);
}
public void sendCab(Visitor visitor) {
for (Customer customer : customers) {
customer.accept(visitor);
}
}
}
// 测试
public class VisitorPatternDemo {
public static void main(String[] args) {
CabCompanyDispatcher dispatcher = new CabCompanyDispatcher();
dispatcher.addCustomer(new Customer("Alice"));
dispatcher.addCustomer(new Customer("Bob"));
Visitor taxi = new Taxi();
// 调度员派出租车访问所有客户
dispatcher.sendCab(taxi);
}
}
