设计模式访问者模式(VisitorPattern)

核心模块:抽象访问者、具体访问者、抽象元素、具体元素、对象结构

所有代码请访问:git@code.aliyun.com:289804201/PatternLearn.git

目的:封装一些施加于某种数据元上上的操作,使不改变元素类的情况下定义作用于这个元素的新操作;
使用场景:数据元很少改变,但是数据元上的操作经常改变;
优点:方便添加新操作,有关元素对象的访问行为集中到一个访问者对象中,而不是分散到一个个的元素类中;
缺点:新增元素困难,因为要在抽象访问者中新增访问方法;
注意:
1,用于结构很少变化的系统中;

2,对象结构中存储了不同类型的元素对象,其基类是抽象元素,一般要遍历list或者map;


/**
 * Created by tory on 2017/12/5.
 * 访问者模式
 */
public class VisitorPattern {
    public static void main(String[] args) {
        ObjectStructure os = new ObjectStructure();
        os.addElement(new ConcreteElementNodeA());
        os.addElement(new ConcreteElementNodeB());

        os.action(new ConcreteVisitorA());
        os.action(new ConcreteVisitorB());
    }
}

//实用场景:1,对同一个对象有不同的使用场景;比如药房和收费两个访问者对药品的访问;不同的访问者与元素类关系不大,但是是一个易变的操作
//2,适用于数据结构相对稳定的系统
//特性:访问者可以扩展,元素类可扩展

//抽象访问者
interface IVisitor {
    //定义访问者可以访问哪些元素
    // FIXME: 2017/12/5 参数为可以扩展,访问者层次扩展
    void visit(ConcreteElementNodeA node);

    void visit(ConcreteElementNodeB node);
}

//具体访问者A
class ConcreteVisitorA implements IVisitor {
    //它影响到访问者访问到一个类后该干什么
    @Override
    public void visit(ConcreteElementNodeA node) {
        //拿到对象A后做什么操作
        System.out.println("我是访问者A");
        System.out.println("fuck"+node.operationA());
    }

    @Override
    public void visit(ConcreteElementNodeB node) {
        //拿到对象B后做什么
        System.out.println("我是访问者A");
        System.out.println("去你妈的"+node.operationB());
    }
}

//具体访问者A
class ConcreteVisitorB implements IVisitor {
    @Override
    public void visit(ConcreteElementNodeA node) {
        System.out.println("我是访问者B");
        System.out.println("hello" + node.operationA());
    }

    @Override
    public void visit(ConcreteElementNodeB node) {
        System.out.println("我是访问者B");
        System.out.println("你好" + node.operationB());
    }
}

//抽象元素类,声明接受哪一类访问者访问
abstract class ElementNode {
    //这里为接受Visitor这一类访问者,元素类可扩展
    abstract void accept(IVisitor visitor);
}

//具体元素A
class ConcreteElementNodeA extends ElementNode {
    @Override
    void accept(IVisitor visitor) {
        //IVisitor代表不同的访问者对元素A的访问
        visitor.visit(this);
    }

    String operationA() {
        return ConcreteElementNodeA.class.getSimpleName();
    }
}

//具体元素B
class ConcreteElementNodeB extends ElementNode {
    @Override
    void accept(IVisitor visitor) {
        //IVisitor代表不同的访问者对元素B的访问
        visitor.visit(this);
    }

    String operationB() {
        return ConcreteElementNodeB.class.getSimpleName();
    }
}

//存储了不同类型的元素对象,以便变不同的访问者访问
class ObjectStructure {
    private List<ElementNode> list = new ArrayList<>();

    void action(IVisitor visitor) {
        for (ElementNode node : list) {
            node.accept(visitor);
        }
    }

    void addElement(ElementNode node) {
        list.add(node);
    }
}

内容打印
Hello World!
我是访问者A
fuckConcreteElementNodeA
我是访问者A
去你妈的ConcreteElementNodeB
我是访问者B
helloConcreteElementNodeA
我是访问者B
你好ConcreteElementNodeB

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值