设计模式-20-访问者模式

来源:互联网 发布:程序员离职能干嘛 编辑:程序博客网 时间:2024/06/05 16:48

访问者模式:主要将数据结构与数据操作分离。

例如:
生老病死乃常态,是我们每个人都逃脱不了的,所以进医院就是一件再平常不过的事情了。在医院看病,你首先的挂号,然后找到主治医生,医生呢?先给你稍微检查下,然后就是各种处方单(什么验血、CD、B超等等,太坑了。。。。),再然后就给你一个处方单要你去拿药。拿药我们可以分为两步走,第一步,我们要去交钱,划价人员会根据你的处方单上面的药进行划价,交钱。第二步,去药房拿药,药房工作者同样根据你的处方单给你相对应的药。

数据:医生开的处方单
操作:
           划价人员根据处方单,进行划价
           药房工作人员,根据处方单,拿药

有时候我们对同一个对象可能会有不同的处理,对相同元素对象也可能存在不同的操作方式,如处方单,划价人员要根据它来划价,药房工作者要根据它来给药。而且可能会随时增加新的操作,如医院增加新的药物。但是这里有两个元素是保持不变的,或者说很少变:划价人员和药房工作中,变的只不过是他们的操作。所以我们想如果能够将他们的操作抽象化就好了。


代码:



抽象访问者(访问划价单)

package com.actionPattern.visitor.edition1;/* * 抽象访问者:Visitor */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);}



划价员:

package com.actionPattern.visitor.edition1;/* * 具体访问者:划价员、Charger */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());    }}



药房工作者

package com.actionPattern.visitor.edition1;/* * 具体访问者:药房工作者、WorkerOfPharmacy */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());    }}



划价单中药品的抽象类

package com.actionPattern.visitor.edition1;/* *  抽象元素:Medicine(划价单中药品的抽象类) */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);}



药品具体的类

package com.actionPattern.visitor.edition1;/* * 具体元素:MedicineA(划价单中药品的具体一类MedicineA) */public class MedicineA extends Medicine{    public MedicineA(String name, double price) {        super(name, price);    }    public void accept(Visitor visitor) {        visitor.visitor(this);    }}


package com.actionPattern.visitor.edition1;/* * 具体元素:MedicineB(划价单中药品的具体一类MedicineB) */public class MedicineB extends Medicine{    public MedicineB(String name, double price) {        super(name, price);    }    public void accept(Visitor visitor) {        visitor.visitor(this);    }}



划价单

package com.actionPattern.visitor.edition1;import java.util.ArrayList;import java.util.Iterator;import java.util.List;/* * 划价单:Presciption */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);    }}



客户端

package com.actionPattern.visitor.edition1;/* * 客户端:Client */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);    }}