# 23种设计模式-访问者模式

# 1.访问者模式

表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

# 优缺点

# 优点:

访问者模式增加新的操作很容易 , 只需要增加一个新的访问者即可 ; 将相关的行为 , 封装到一个访问者中 ;

# 缺点:

增加 新数据结构比较困难 元素变更比较困难 ; 如为被访问的对象增加 / 减少一些属性 , 相应的访问者也需要进行修改 ;

# 使用场景

# 实现方式

# 抽象访问者:Visitor.java

public abstract class Visitor {
    protected String name;
 
    public void setName(String name) {
        this.name = name;
    }
    
    public abstract void visitor(MedicineA a);
    
    public abstract void visitor(MedicineB b);
}

# 具体访问者:划价员、Charger.java

public class Charger extends Visitor{
 
    public void visitor(MedicineA a) {
        System.out.println("划价员:" + name +"给药" + a.getName() +"划价:" + a.getPrice());
    }
 
    public void visitor(MedicineB b) {
        System.out.println("划价员:" + name +"给药" + b.getName() +"划价:" + b.getPrice());
    }
}

# 具体访问者:药房工作者、WorkerOfPharmacy.java

public class WorkerOfPharmacy extends Visitor{
 
    public void visitor(MedicineA a) {
        System.out.println("药房工作者:" + name + "拿药 :" + a.getName());
    }
 
    public void visitor(MedicineB b) {
        System.out.println("药房工作者:" + name + "拿药 :" + b.getName());
    }
}

# 抽象元素:Medicine.java

public abstract class Medicine {
    protected String name;
    protected double price;
 
    public Medicine (String name,double price){
        this.name = name;
        this.price = price;
    }
    
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public double getPrice() {
        return price;
    }
    
    public void setPrice(double price) {
        this.price = price;
    }
    
    public abstract void accept(Visitor visitor);
}

# 具体元素:MedicineA.java MedicineB.java

public class MedicineA extends Medicine{
 
    public MedicineA(String name, double price) {
        super(name, price);
    }
 
    public void accept(Visitor visitor) {
        visitor.visitor(this);
    }
}

public class MedicineB extends Medicine{
 
    public MedicineB(String name, double price) {
        super(name, price);
    }
 
    public void accept(Visitor visitor) {
        visitor.visitor(this);
    }
}

# 药单:Presciption.java

public class Presciption {
    List<Medicine> list = new ArrayList<Medicine>();
    
    public void accept(Visitor visitor){
        Iterator<Medicine> iterator = list.iterator();
        
        while (iterator.hasNext()) {
            iterator.next().accept(visitor);
        }
    }
    
    public void addMedicine(Medicine medicine){
        list.add(medicine);
    }
    
    public void removeMedicien(Medicine medicine){
        list.remove(medicine);
    }
}

# 测试类

public class Client {
    public static void main(String[] args) {
        Medicine a = new MedicineA("板蓝根", 11.0);
        Medicine b = new MedicineB("感康", 14.3);
        
        Presciption presciption = new Presciption();
        presciption.addMedicine(a);
        presciption.addMedicine(b);
        
        Visitor charger = new Charger();
        charger.setName("张三");
        
        Visitor workerOfPharmacy = new WorkerOfPharmacy();
        workerOfPharmacy.setName("李四");
        
        presciption.accept(charger);
        System.out.println("-------------------------------------");
        presciption.accept(workerOfPharmacy);
    }
}

参考博客:https://blog.csdn.net/a745233700/article/details/83721344