访问者模式


1. 类图

image.png

  • Visitor:访问者接口,为所有访问者声明一个方法,用来代表对对象结构添加的功能
  • ConcreteVisitor:具体访问者,实现添加的功能
  • Element:元素对象,对象结构的顶层接口,定义接收访问的操作
  • ConcreteElement:具体元素对象,回调访问者的真实功能,开放自身的数据供访问者使用
  • ObjectStructure:对象结构,包含多个被访问的对象

2. 示例

为可能扩展的对象预留回路,通过回调的方式进行功能扩展,避免对对象的修改

2.1 现有对象抽象类

public abstract class Customer {
    private String id;
    private String name;

    // 接受访问者访问
    public abstract void accetp(Visitor visitor);
}

2.2 现有对象实现

public class PersonCustomer extends Customer {
    private String name;
    private int age;

    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public int getAge() {return age;}
    public void setAge(int age) {this.age = age;}

    @Override
    public void accetp(Visitor visitor) {
        // 回调访问者对象对应方法
        visitor.visitPerson(this);
    }
}

public class EnterpriseCustomer extends Customer {
    private String linkman;
    private String linkPhone;
    private String regAddr;

    public String getLinkman() {return linkman;}
    public void setLinkman(String linkman) {this.linkman = linkman;}
    public String getLinkPhone() {return linkPhone;}
    public void setLinkPhone(String linkPhone) {this.linkPhone = linkPhone;}
    public String getRegAddr() {return regAddr;}
    public void setRegAddr(String regAddr) {this.regAddr = regAddr;}

    @Override
    public void accetp(Visitor visitor) {
        // 回调访问者对象对应方法
        visitor.vistiEnterprise(this);
    }
}

2.3 访问者接口

为目标对象添加扩展功能

public interface Visitor {
    // 访问个人用户
    void visitPerson(PersonCustomer personCustomer);
    // 访问企业用户
    void vistiEnterprise(EnterpriseCustomer enterpriseCustomer);
}

2.4 具体访问者

为目标对象添加功能实现

public class ServiceRequestVisitor implements Visitor {
    @Override
    public void visitPerson(PersonCustomer personCustomer) {
        System.out.println("个人用户:" + personCustomer.getName() + "请求服务");
    }

    @Override
    public void vistiEnterprise(EnterpriseCustomer enterpriseCustomer) {
        System.out.println("企业用户:" + enterpriseCustomer.getLinkman() + "请求服务");
    }
}

2.5 对象结构

保存需要扩展的对象,触发扩展的方法

public class ObjectStructure {
    private List<Customer> customerList = new ArrayList<>();
    // 触发扩展功能
    public void handle(Visitor visitor){
        for (Customer customer : customerList) {
            customer.accetp(visitor);
        }
    }

    public void addElement(Customer customer){this.customerList.add(customer);}
}

2.6 客户端

public class Client {
    public static void main(String[] args) {
        // 用户创建
        PersonCustomer personCustomer = new PersonCustomer();
        personCustomer.setName("hiloj");
        personCustomer.setAge(18);

        EnterpriseCustomer enterpriseCustomer = new EnterpriseCustomer();
        enterpriseCustomer.setLinkman("hiloj");
        enterpriseCustomer.setLinkPhone("88888888");
        enterpriseCustomer.setRegAddr("东方明珠第8层");

        // 创建对象结构
        ObjectStructure os = new ObjectStructure();
        os.addElement(personCustomer);
        os.addElement(enterpriseCustomer);

        // 客户提出请求服务
        ServiceRequestVisitor serviceRequestVisitor = new ServiceRequestVisitor();
        os.handle(serviceRequestVisitor);

    }
}

3. 优点

  • 好的扩展性和复用性
  • 分离无关的变化

4. 缺点

  • 对象结构变化困难
  • 破坏封装
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值