设计模式 - 学习笔记 - 访问者模式VisitorPattern

Posted 笑虾

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式 - 学习笔记 - 访问者模式VisitorPattern相关的知识,希望对你有一定的参考价值。

学习总结

  1. 访问者模式的目的是将数据与操作数据的行为解构开,针对已知的数据(Element),可以扩展不同的处理行为(Visitor).
  2. Element接口养身保健的服务(数据)是固定的(比如只有4个)。
  3. 访问者Visitor接口决定所有访问者都知道Element接口4个数据
  4. 可扩展点就是访问者。通过实现新访问者扩展操作数据的行为。
  5. 局限在于保健服务(数据)定死了。如果需要添加新服务(数据),那么所有访问者都要变。( 体现在Visitor接口依赖了Element实现类)
  6. 从UML图中可以看到能扩展的部分即实现Visitor,其它内容都是固定的,所以此模式相对来说比较重度。

基本逻辑

  1. 创建数据接口Element,定义accept(Visitor vsitor)方法来接受访问者。
    1.1. 实现N个具体数据类ConcreteElementAConcreteElementBConcreteElementC。。。
    1.2. 具体实现细节在第4步再说。(先把类创建好,下一步要用到)
  2. 创建访问者接口Visitor,定义访问方法visit(ConcreteElement element)来访问数据。
    2.1. 注意参数是具体数据类。有多少个ConcreteElement?,就重载多少次visit
  3. 创建Visitor实现类,实现visit方法,访问数据处理业务逻辑。(此处为扩展点)
  4. 创建Element实现类,实现accept(Visitor vsitor)方法。
    4.1. 在accept方法内,调用visitor.visit(this)方法,达到让访问者访问自己的目的。
  5. 【下文中未实现】通常为了让客户端方便批量访问所有ConcreteElement。需要创建一个辅助的对象结构 ObjectStructure
    5.1. 内部维护一个Element容器,支持添加移除批量accept

UML

代码示例

养身保健接口(数据)

public interface Element
    /** 接待一位访问者 */
    void accept(Visitor visitor);

具体养身保健服务

/** 按摩 */
public class Massage implements Element
    @Override
    public void accept(Visitor visitor)  visitor.visit(this); 

/** 针灸 */
public class Acupuncture implements Element 
    @Override
    public void accept(Visitor visitor)  visitor.visit(this); 

/** 拔火罐 */
public class Cupping implements Element
    @Override
    public void accept(Visitor visitor)  visitor.visit(this); 

/** 一条龙服务 */
public class OnePackageService implements Element 
    @Override
    public void accept(Visitor visitor)  visitor.visit(this); 

访问者接口(行为)

/**
 * 访问者接口
 * @author jerryjin
 */
public interface Visitor 
    /** 体验按摩服务 */
    void visit(Massage massage);
    /** 体验针灸服务 */
    void visit(Acupuncture acupuncture);
    /** 体验拔火罐服务 */
    void visit(Cupping cupping);
    /** 体验一条龙服务 */
    void visit(OnePackageService onepackageservice);

具体访问者

程序猿

public class Programmer implements Visitor 
    /** 体验按摩服务 */
    @Override
    public void visit(Massage massage) 
        System.out.println("“" + this.getClass().getSimpleName() + "”拒绝了" + massage.getClass().getSimpleName() + "服务。");
    

    /** 体验针灸服务 */
    @Override
    public void visit(Acupuncture acupuncture) 
        System.out.println("“" + this.getClass().getSimpleName() + "”拒绝了" + acupuncture.getClass().getSimpleName() + "服务。");
    

    /** 体验拔火罐服务 */
    @Override
    public void visit(Cupping cupping) 
        System.out.println("“" + this.getClass().getSimpleName() + "”体验了" + cupping.getClass().getSimpleName() + "服务,给了☆☆☆☆☆好评!");
    

    /** 体验一条龙服务 */
    @Override
    public void visit(OnePackageService onepackageservice) 
        System.out.println("“" + this.getClass().getSimpleName() + "”拒绝了" + onepackageservice.getClass().getSimpleName() + "服务。");
    

old镖客

public class OldPiaoKe implements Visitor 
    /** 体验按摩服务 */
    @Override
    public void visit(Massage massage) 
        System.out.println("“" + this.getClass().getSimpleName() + "”拒绝了" + massage.getClass().getSimpleName() + "服务。");
    

    /** 体验针灸服务 */
    @Override
    public void visit(Acupuncture acupuncture) 
        System.out.println("“" + this.getClass().getSimpleName() + "”拒绝了" + acupuncture.getClass().getSimpleName() + "服务。");
    

    /** 体验拔火罐服务 */
    @Override
    public void visit(Cupping cupping) 
        System.out.println("“" + this.getClass().getSimpleName() + "”拒绝了" + cupping.getClass().getSimpleName() + "服务。");
    

    /** 体验一条龙服务 */
    @Override
    public void visit(OnePackageService onepackageservice) 
        System.out.println("“" + this.getClass().getSimpleName() + "”体验了" + onepackageservice.getClass().getSimpleName() + "服务,给了☆☆☆☆☆好评!");
    

Client 客户端

package com.jerry.designpattern.visitor;

import ...

/**
 * 这里在很正经洗脚城。
 * 欢迎各位访客前来体验。
 * @author jerryjin
 */
public class VisitorDemo 
    public static void main(String[] args) 
        Massage massage = new Massage();
        Acupuncture acupuncture = new Acupuncture();
        Cupping cupping = new Cupping();
        OnePackageService onePackageService = new OnePackageService();

        Visitor programmer = new Programmer();
        Visitor oldPiaoKe = new OldPiaoKe();

        System.out.println("====================程序员==================");
        massage.accept(programmer);
        acupuncture.accept(programmer);
        cupping.accept(programmer);
        onePackageService.accept(programmer);
        
        System.out.println("====================old镖客==================");
        massage.accept(oldPiaoKe);
        acupuncture.accept(oldPiaoKe);
        cupping.accept(oldPiaoKe);
        onePackageService.accept(oldPiaoKe);
    

运行结果

====================程序员==================
“Programmer”拒绝了Massage服务。
“Programmer”拒绝了Acupuncture服务。
“Programmer”体验了Cupping服务,给了☆☆☆☆☆好评!
“Programmer”拒绝了OnePackageService服务。
====================old镖客==================
“OldPiaoKe”拒绝了Massage服务。
“OldPiaoKe”拒绝了Acupuncture服务。
“OldPiaoKe”拒绝了Cupping服务。
“OldPiaoKe”体验了OnePackageService服务,给了☆☆☆☆☆好评!

参考资料

以上是关于设计模式 - 学习笔记 - 访问者模式VisitorPattern的主要内容,如果未能解决你的问题,请参考以下文章

设计模式学习笔记--访问者模式

访问者模式——HeadFirst设计模式学习笔记

java/android 设计模式学习笔记(24)---访问者模式

Java设计模式学习笔记

设计模式 - 学习笔记 - 观察者模式ObserverPattern

设计模式 - 学习笔记 - 观察者模式ObserverPattern