美文网首页野生技术宅协会
设计模式(二十四) 访问者模式

设计模式(二十四) 访问者模式

作者: 乐百川 | 来源:发表于2017-04-06 01:25 被阅读22次

访问者模式提供了一种方法,将算法和数据结构分离。假设我们需要对一个数据结构进行不同的操作,就可以考虑使用访问者模式。访问者模式的要点在于,需要一个访问者接口,提供了一些重载方法来访问具体对象。对于每个具体对象,又提供了一个accept方法来回调访问者。

首先来看看访问者。

public interface Visitor {
    void visit(House house);

    void visit(Kitchen kitchen);

    void visit(LivingRoom livingRoom);

    void visit(BedRoom bedRoom);
}

class HouseVisitor implements Visitor {
    public void visit(House house) {
        System.out.println("访问了房子");
    }

    public void visit(BedRoom bedRoom) {
        System.out.println("访问了卧室");
    }

    public void visit(LivingRoom livingRoom) {
        System.out.println("访问了客厅");
    }

    public void visit(Kitchen kitchen) {
        System.out.println("访问了厨房");
    }
}

然后是要访问的对象,这里是一间屋子。

public class House {
    private LivingRoom livingRoom;
    private Kitchen kitchen;
    private BedRoom bedRoom;

    public House() {
        livingRoom = new LivingRoom();
        kitchen = new Kitchen();
        bedRoom = new BedRoom();
    }

    public void accept(Visitor visitor) {
        visitor.visit(this);
        livingRoom.accept(visitor);
        bedRoom.accept(visitor);
        kitchen.accept(visitor);
    }
}

class LivingRoom {
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

class Kitchen {
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

class BedRoom {
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

然后客户端就可以简单的访问屋子了。

    public void run() {
        Visitor visitor = new HouseVisitor();
        House house = new House();
        visitor.visit(house);
    }

这就是访问者模式了。可能会同学会有疑问,为什么我要这么写?如果让屋子对象层次全部都实现Visitor接口,然后客户端直接调用这些visit方法不是也可以吗?一开始我也有这个疑问,后来看了知乎轮子哥的一篇文章ParserGen生成预定义好的各种visitor,感觉茅塞顿开。

其实Visitor模式讲的就是在不需要扩充新的子类的时候,如何添加新的虚函数而不需要修改原有代码。当然虚函数也有它的好处,就是添加新的子类的时候不需要修改原有代码。所以看你的业务逻辑,到底是添加新子类多,还是添加新虚函数多,从而选择要不要把程序写成基于Visitor模式的样子。

对于编译器来说,整个处理流程那么复杂,所以等于需要经常添加虚函数,因此就都把本来是虚函数的东西改成了各种Visitor。这个时候,如果你修改了语法,那么每一个Visitor都会曝出语法错误,所以这等于变相通知你所有需要修改的东西在哪里——如果你能坚持不因为偷懒而使用dynamic_cast的话。

所谓设计模式,都需要在特定的环境中才有用。所以现在我们已经了解了什么情况下应该使用访问者模式。假如接口中的方法固定,但是需要添加新的实现类,那么就使用普通的继承方式。如果接口方法经常变动,就可以把接口改写为访问者。

相关文章

  • [Android]设计模式-访问者模式

    [Android]设计模式-访问者模式 访问者模式 Visitor 【备注】只用于个人收藏

  • 设计模式[23]-访问者模式-Visitor Pattern

    1.访问者模式简介 访问者模式(Visitor Pattern)模式是行为型(Behavioral)设计模式,提供...

  • 设计模式之访问者(Visitor)

    访问者模式,是行为型设计模式之一。访问者模式是一种将数据操作与数据结构分离的设计模式,它可以算是 23 中设计模式...

  • 访问者模式一篇就够了

    访问者模式介绍 最复杂的设计模式,并且使用频率不高,《设计模式》的作者评价为:大多情况下,你不需要使用访问者模式,...

  • 访问者模式

    访问者模式属于行为型模式。访问者模式是一种将数据结构和数据操作分离的设计模式。访问者模式比较复杂,而且实际使用的地...

  • Android设计模式——访问者模式(十一大行为型)

    1.访问者模式介绍 访问者模式时十一大行为型设计模式之一。 访问者模式是一种将数据操作与数据结构分...

  • 手撸golang 行为型设计模式 访问者模式

    手撸golang 行为型设计模式 访问者模式 缘起 最近复习设计模式拜读谭勇德的<<设计模式就该这样学>>本系列笔...

  • 25.访问者模式(行为型)

    访问者模式(行为型) 一、相关概述 访问者模式是一种较为复杂的行为型设计模式,它包含访问者和被访问元素两个主要组成...

  • Java设计模式<访问者模式>

    Java设计模式<访问者模式> 意图 将对象的结构和操作分离 角色 抽象访问者:抽象类或者接口,声明访问者可以访问...

  • 访问者模式

    访问者模式属于行为变化模式。在GOF的《设计模式:可复用面向对象软件的基础》一书中对访问者模式是这样说的:表示一个...

网友评论

    本文标题:设计模式(二十四) 访问者模式

    本文链接:https://www.haomeiwen.com/subject/hnrfattx.html