设计模式之访问者模式
题目
[实验任务一]:打包员
在我们课堂上的“购物车”的例子中,增加一个新的访问者:打包员,负责对购物车中货物装包。
类图:
类图
Java
Product
package com.gazikel;
public interface Product {
void accept(Visitor visitor);
}
Product实现类
Apple
package com.gazikel;
public class Apple implements Product {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
Book
package com.gazikel;
public class Book implements Product {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
Visitor
package com.gazikel;
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);
}
Visitor实现类
Customer
package com.gazikel;
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 + "买书");
}
}
Packer
package com.gazikel;
public class Packer extends Visitor {
@Override
public void visit(Apple apple) {
System.out.println("打包员" + name + "给苹果打包");
}
@Override
public void visit(Book book) {
System.out.println("打包员" + name + "给书打包");
}
}
Saler
package com.gazikel;
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 + "直接计算书的价格");
}
}
BuyBasket
package com.gazikel;
import java.util.ArrayList;
import java.util.List;
public class BuyBasket {
private List<Product> products = new ArrayList();
public void accept(Visitor visitor) {
for (Product product : products) {
product.accept(visitor);
}
}
public void addProduct(Product p) {
products.add(p);
}
public void removeProduct(Product p) {
products.remove(p);
}
}
Client
package com.gazikel;
public class Client {
public static void main(String[] args) {
BuyBasket buyBasket = new BuyBasket();
buyBasket.addProduct(new Apple());
buyBasket.addProduct(new Book());
Visitor saler = new Saler();
saler.setName("张三");
System.out.println("----收银员----");
buyBasket.accept(saler);
Visitor packer = new Packer();
packer.setName("李四");
System.out.println("----打包员----");
buyBasket.accept(packer);
Visitor customer = new Customer();
customer.setName("王五");
System.out.println("----顾客----");
buyBasket.accept(customer);
}
}
C++
main.cpp
#include <iostream>
#include <string>
#include <list>
using namespace std;
class Product;
class Book;
class Apple;
class Visitor
{
protected:
string name;
public:
void SetName(string name) {
this->name = name;
}
virtual void Visit(Apple *apple) {};
virtual void Visit(Book *book) {};
};
class Product
{
public:
// Methods
virtual void Accept(Visitor *visitor) {};
};
// "ConcreteElement"
class Apple : public Product {
public:
void Accept(Visitor *visitor) {
visitor->Visit(this);
}
};
class Book :public Product {
public:
void Accept(Visitor* visitor) {
visitor->Visit(this);
}
};
class Customer : public Visitor {
public:
void Visit(Book *book) {
cout << "顾客" << name << "买书" << endl;
}
void Visit(Apple *apple) {
cout << "顾客" << name << "选苹果" << endl;
}
};
class Saler : public Visitor {
public:
void Visit(Book *book) {
cout << "收银员" << name << "直接计算书的价格" << endl;
}
void Visit(Apple *apple) {
cout << "收银员" << name << "给苹果过秤,然后计算其价格" << endl;
}
};
class Packer : public Visitor {
public:
void Visit(Book *book) {
cout << "打包员" << name << "给书打包" << endl;
}
void Visit(Apple *apple) {
cout << "打包员" << name << "给苹果打包" << endl;
}
};
// "ObjectStructure"
class BuyBasket
{
private:
list<Product*> products;
public:
void Attach(Product *product)
{
products.push_back(product);
}
void Detach(Product *product)
{
products.remove(product);
}
void Accept(Visitor *visitor)
{
for (std::list<Product*>::iterator it = products.begin(); it != products.end(); ++it)
(*it)->Accept(visitor);
}
};
int main()
{
BuyBasket *buybasket = new BuyBasket();
Product* apple = new Apple();
Product* book = new Book();
buybasket->Attach(apple);
buybasket->Attach(book);
Customer *customer = new Customer();
customer->SetName("张三");
Saler* saler = new Saler();
saler->SetName("李四");
Packer* packer = new Packer();
packer->SetName("王五");
// Employees are visited
cout << "----customer----" << endl;
buybasket->Accept(customer);
cout << "----saler----" << endl;
buybasket->Accept(saler);
cout << "----packer----" << endl;
buybasket->Accept(packer);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
2020-11-27 response常用的方法
2020-11-27 2020.11.27小记