设计模式之访问者模式

本文介绍了访问者模式,一种行为设计模式,用于处理一组具有相同类型的对象。通过实例化的购物车案例,展示了如何创建商品接口、商品实体、访问者接口和访问者实体,以及测试过程。访问者模式的优势在于当操作逻辑变动时,只需更改访问者实现,不需修改原有商品类,同时方便添加新的商品类别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总体来说设计模式分为三大类:
创建型模式5种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式7种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

访问者模式

访问者模式是一种行为设计模式。访问者模式被用在针对一组相同类型对象的操作

Demo:购物车案例

首先,创建商品类型接口
public interface ItemElement {

    public int accept(ShoppingCartVisitor visitor);//参数传入的是访问者
}
其次,创建商品类型实体类
public class Book implements ItemElement {

    private int price;
    private String isbnNumber;// 国际标准图书编号

    public Book(int cost, String isbn){
        this.price=cost;
        this.isbnNumber=isbn;
    }

    public int getPrice() {
        return price;
    }

    public String getIsbnNumber() {
        return isbnNumber;
    }

    @Override
    public int accept(ShoppingCartVisitor visitor) {
        return visitor.visit(this);
    }

}
public class Fruit implements ItemElement {

    private int pricePerKg;//每公斤价格
    private int weight;
    private String name;

    public Fruit(int priceKg, int wt, String nm){
        this.pricePerKg=priceKg;
        this.weight=wt;
        this.name = nm;
    }

    public int getPricePerKg() {
        return pricePerKg;
    }

    public int getWeight() {
        return weight;
    }

    public String getName(){
        return this.name;
    }

    @Override
    public int accept(ShoppingCartVisitor visitor) {
        return visitor.visit(this);
    }

}
然后,创建访问者接口
public interface ShoppingCartVisitor {

    int visit(Book book);
    int visit(Fruit fruit);
}
其后,创建访问者实体类
public class ShoppingCartVisitorImpl implements ShoppingCartVisitor {

    @Override
    public int visit(Book book) {
        int cost=0;
        if(book.getPrice() > 50){//当书的价格高于50¥,减价5¥
            cost = book.getPrice()-5;
        }else cost = book.getPrice();
        System.out.println("书编:"+book.getIsbnNumber() + "的价格="+cost);
        return cost;
    }

    @Override
    public int visit(Fruit fruit) {
        int cost = fruit.getPricePerKg()*fruit.getWeight();
        System.out.println(fruit.getName() + "的价格 = "+cost);
        return cost;
    }

}
接着,创建测试类
public class ShoppingCartClient {

    public static void main(String[] args) {
        ItemElement[] items = new ItemElement[]{new Book(20, "1234"),new Book(100, "5678"),
                new Fruit(10, 2, "香蕉"), new Fruit(5, 5, "苹果")};

        int total = calculatePrice(items);
        System.out.println("总花费 = "+total);
    }

    private static int calculatePrice(ItemElement[] items) {
        ShoppingCartVisitor visitor = new ShoppingCartVisitorImpl();
        int sum=0;
        for(ItemElement item : items){
            sum = sum + item.accept(visitor);
        }
        return sum;
    }

}
最后,查看输出结果


书编:1234的价格 = 20
书编:5678的价格 = 95
香蕉的价格= 20
苹果的价格= 25
总花费= 160

优点
①如果操作的逻辑改变,我们只需要改变访问者的实现就够了,而不用去修改其他所有的商品类。
②添加新类别的商品到系统变得容易。只需要改变一下访问者接口以及其实现。已经存在的商品类别不会被干扰影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值