设计模式-访问者模式(Visitor)

访问者模式是一种将数据操作与数据结构分离的设计模式,它的实现主要就是通过预先定义好调用的通路,在被访问的对象上定义accept方法,在访问者的对象上定义visit方法;然后在调用真正发生的时候,通过两次分发的技术,利用预先定义好的通路,回调到访问者具体的实现上。主要解决现已稳定的数据结构和易变的操作耦合问题,把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。如果所有数据结构一致,可以抽象出公共接口,则数据结构和操作皆可以自由扩展。

public interface Visitor {  
    public void visit(Subject sub);  
}  
#访问者 visit方法
public class MyVisitor implements Visitor {  
  
    @Override  
    public void visit(Subject sub) {  
        System.out.println("visit the subject:"+sub.getSubject());  
    }  
}  

#Subject类,accept方法,接受将要访问它的对象,getSubject()获取将要被访问的属性,
public interface Subject {  
    public void accept(Visitor visitor);  
    public String getSubject();  
}  
#数据结构
public class MySubject implements Subject {  
  
    @Override  
    public void accept(Visitor visitor) {  
        visitor.visit(this);  
    }  
  
    @Override  
    public String getSubject() {  
        return "love";  
    }  
}  

public class Test {  
    public static void main(String[] args) {  
        Visitor visitor = new MyVisitor();  
        Subject sub = new MySubject();  
        sub.accept(visitor);      
    }  
}  

 

下面是我这边从网上找的一段示例代码,觉得还可以,借来用下:

//员工基类
public abstract class Staff {
    public String name;
    //员工kpi
    public int kpi;

    public Staff(String name) {
        this.name = name;
        kpi = new Random().nextInt(10);
    }
    //接收Visitor的访问
    public abstract void accept(Visitor visitor);
}

//工程师
public class Engineer extends Staff {
    public Engineer(String name) {
        super(name);
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    //工程师这一年写的代码数量
    public int getCodeLines(){
        return new Random().nextInt(10*10000);
    }
}

//经理类型
public class Manager extends Staff {
    private int products; // 产品数量
    public Manager(String name) {
        super(name);
        products = new Random().nextInt(10);
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    //一年内做的产品数量
    public int getProducts(){
        return products;
    }
}

// 员工业务报表1类
public class BusinessReport {
    List<Staff> mStaffs = new LinkedList<Staff>();

    public BusinessReport() {
        mStaffs.add(new Manager("米经理"));
        mStaffs.add(new Engineer("工程师-jia"));
        mStaffs.add(new Engineer("工程师-wei"));
        mStaffs.add(new Engineer("工程师-wang"));
        mStaffs.add(new Engineer("工程师-shi"));
    }

    /** * 为访问者展示报表 * @param visitor */
    public void showReport(Visitor visitor){
        for (Staff staff : mStaffs){
            staff.accept(visitor);
        }
    }
}

//访问者接口
public interface Visitor {
    //访问工程师类型
    public void visit(Engineer engineer);
    //访问经理类型
    public void visit(Manager leader);
}

//CEO访问者,只关注业绩
public class CEOVisitor implements Visitor {
    @Override
    public void visit(Engineer engineer) {
        System.out.println("工程师:" + engineer.name + ",KPI:" + engineer.kpi);
    }

    @Override
    public void visit(Manager leader) {
        System.out.println("经理:" + leader.name + ", KPI:" + leader.kpi + ",新产品数量:" + leader.getProducts());
    }
}

public class CTOVisitor implements Visitor {
    @Override
    public void visit(Engineer engineer) {
        System.out.println("工程师:"+engineer.name+",代码函数:"+engineer.getCodeLines());
    }

    @Override
    public void visit(Manager leader) {
        System.out.println("经理:"+leader.name+",产品数量:"+leader.getProducts());
    }
}

//客户端代码
public class Client {
    public static void main(String[] args){
        //构建报表
        BusinessReport report = new BusinessReport();
        System.out.println("==========给CEO看的报表=========");
        //设置访问者,这里是CEO
        report.showReport(new CEOVisitor());
        System.out.println("==========给CTO看的报表=========");
        //注入另一个访问者CTO
        report.showReport(new CTOVisitor());
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值