【设计模式】访问者模式 Visitor pattern

Today, we are going to talk about one of the most useful design pattern: Visitor pattern.


Advantage

The essential of using visitor pattern is that it allow us to add functions dynamically.


UML

Let’s see the diagram of this pattern (which I downloaded from Wikipedia).
Visitor pattern in UML


Structure

First of all, the class named Client on the upper left corner is just a normal class (We can have a main function in this class) that allow us to use the instance of concrete visitor classes.

Then the Element class is a class that contains specified data or object or just a super class of a concrete element. Moreover, as I wrote before, we can also a concrete element class that inherit Element, in the image above, its name is ConcreteElement.
Attention: All classes that accept visitor must have a method

accept(Visitor);

So that it can be visited(return its instance to the Visitor) by the Visitor.
The implementation of a concrete class is just like this:

public Piano extends Element{
    public void accept(Visitor v){
        v.visit(this);//As you can see, here we have returned the instance of Piano. So that it will invoke the suitable function implemented in a visitor.
    }
    public void play(){
        playThePiano();
    }
}

Well, perhaps somebody might still not clear about Element and ConcreteElement. For instance, we have a class named Animal which is an Element. Then, we have some classes named Dog, Cat, Elephant that inherited from Animal which are a kind of ConcreteElement.

Last but the most important. We can see there is an interface called Visitor and a ConcreteVisitor which implements the interface. Well, this is the most important things. As we want to add some functions in decades before, we have to modify every class which is of non-sense. However, after Visitor Pattern has been invented, our jobs became much more easier. When we want to add some functions, we just need to create a class that implements Visitor. Then, in this class, we can create different functions that adapt to different objects.

For instance, suppose we have 3 classes called Computer, Piano, Basketball:

public class PlayVisitor implements Visitor{
    public void visit(Computer c){
        c.turnOn();
        c.launchGames();
        c.play();
    }
    public void visit(Piano p){
        p.play();
    }
    public void visit(Basketball b){
        b.callFriends();
        b.takeBall();
        b.play();
    }
}

We can add functions to an existed project without major modification. Just like codes above, we can implement various types of Visitor using the same method that illustrated above.

Then we can create an instance of PlayVisitor in main.

public class Client{
    public static void main(String args[]){
        Piano piano = new Piano();
        Computer computer = new Computer();
        Basketball basketball = new Basketball();

        piano.accept(new PlayVisitor);
        computer.accept(new PlayVisitor);
        basketball.accept(new PlayVisitor);
        //Here we have created 3 different objects that can be played by the user. Then, for each of them, we invoke its accept function as well as put an instance of PlayVisitor as the parameter.
    }
}

Overall, rather than decorator pattern or some difficult patterns, visitor pattern is not very difficult to be implemented. However, it is very useful for those who have need to add many functions. So that I would like to recommend you to use this design pattern.


Example project:

https://github.com/Voyager2718/Blog/tree/master/VisitorPattern

Run result:

Visitor 1 Time of visit: 1.
Found some friends.
Found a ball.
Playing basketball.

Visitor 1 Time of visit: 2.
Computer turned on.
Game launched.
Playing computer game.

Visitor 2 Time of visit: 1.
Playing piano.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值