访问者模式--Visitor

访问者模式

定义:

  • 《设计模式》一书对于访问者模式给出的定义为:表示一个作用于某对象结构中的各元
    素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作
  • 访问者模式(Vistor Pattern)是一种将数据结构数据操作分离的的设计模式。
访问者模式适用于数据结构相对稳定, 算法又易变化的系统

在这里插入图片描述

组成结构:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

案例 1

需求:

  • 现有一电脑售卖点,电脑是由内存,cpu,和主板三块组成.
  • 对于不同来的购买者,内存,cpu,和主板有不同的优惠.

ComputerPart 抽象元素角色

abstract class ComputerPart {
    abstract void accept(Visitor v);
    //some other operations eg:getName getBrand
    abstract double getPrice();
}

CPU、 Memory、 Board 具体元素角色

class CPU extends ComputerPart {

    @Override
    void accept(Visitor v) {
        v.visitCpu(this);
    }

    @Override
    double getPrice() {
        return 500;
    }
}

class Memory extends ComputerPart {

    @Override
    void accept(Visitor v) {
        v.visitMemory(this);
    }

    @Override
    double getPrice() {
        return 300;
    }
}

class Board extends ComputerPart {

    @Override
    void accept(Visitor v) {
        v.visitBoard(this);
    }

    @Override
    double getPrice() {
        return 200;
    }
}

Computer 对象结构角色

class Computer {

    ComputerPart cpu = new CPU();
    ComputerPart memory = new Memory();
    ComputerPart board = new Board();

    public void acccept(Visitor v) {
        this.cpu.accept(v);
        this.memory.accept(v);
        this.board.accept(v);
    }
}

Visitor 抽象访问中角色

interface Visitor {
    void visitCpu(CPU cpu);
    void visitMemory(Memory memory);
    void visitBoard(Board board);
}

PersonelVisitor 、CorpVisitor 具体访问者 角色

  • PersonelVisitor
class PersonelVisitor implements Visitor {
    double totalPrice = 0.0;

    @Override
    public void visitCpu(CPU cpu) {
        totalPrice += cpu.getPrice()*0.9;
    }

    @Override
    public void visitMemory(Memory memory) {
        totalPrice += memory.getPrice()*0.85;
    }

    @Override
    public void visitBoard(Board board) {
        totalPrice += board.getPrice()*0.95;
    }
}

  • CorpVisitor
class CorpVisitor implements Visitor {
    double totalPrice = 0.0;

    @Override
    public void visitCpu(CPU cpu) {
        totalPrice += cpu.getPrice()*0.6;
    }

    @Override
    public void visitMemory(Memory memory) {
        totalPrice += memory.getPrice()*0.75;
    }

    @Override
    public void visitBoard(Board board) {
        totalPrice += board.getPrice()*0.75;
    }
}

测绘类

public class Main {
    public static void main(String[] args) {
        PersonelVisitor p = new PersonelVisitor();
        new Computer().acccept(p);
        System.out.println("PersonelVisitor: "+p.totalPrice);
    }
}

在这里插入图片描述

双重分派 在这里插入图片描述

案例 2 编译器

抽象语法树:

在这里插入图片描述

传统编程模式 :

  • 在每一个节点Node加一堆方法

在这里插入图片描述

访问者模式:

在这里插入图片描述

访问者模式运用最多,就是在做编译器的时候

总结:

使用场景:

  • 数据结构要稳定,但是作用于数据结构上的操作经常变化 (如上面示例中如果元素价格经常发生变化,那么每次变化都要修改访问者对象)。
  • 需要对不同数据类型(元素)进行操作,而不使用分支判断具体类型的场景。

优点:

  • 符合单一职责原则
  • 访问者角色非常易于扩展
  • 解耦了数据结构和数据操作,使得操作集合可以独立变化

缺点:

  • 具体元素对访问者公布细节,也就是说访问者关注了其他类的内部细节,这是迪米特法则所不建议的
  • 具体元素变更比较困难
  • 违背了依赖倒转原则。访问者依赖的是具体元素,而不是抽象元素

应用:

  • 访问者可以对功能进行统一,可以做报表、UI、拦截器与过滤器。
  • 访问者模式适用于数据结构相对稳定的系统
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值