设计模式——访问者模式

184 阅读2分钟

1. 访问者模式概述

在访问者模式中,我们使用了一个访问者类,它改变了元素类的执行算法。
通过这种方式,元素的执行算法可以随着访问者改变而改变。
根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。

访问者模式不好理解,建议直接看例子。

(1) 适用情况

主要将数据结构与数据操作分离,适用于稳定的数据结构和易变的操作耦合的情况。

(2) 优点

方便拓展、灵活,符合单一职责原则。

(3) 缺点

具体元素对访问者公布细节,违反了迪米特原则。具体元素变更比较困难。违反了依赖倒置原则,依赖了具体类,没有依赖抽象。

2. 访问者模式实例

主人买了个大房子,里面有好多个小房间,客人使用访问者模式来实现对大房子和各个房间的访问。 (1) 定义了房间接口

public interface Room {
    void accept(Visitor visitor);
}

(2) 实现各个房间类

public class Parlor implements Room {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
public class Kitchen implements Room {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
public class Bedroom implements Room {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

(3) 实现大房子类

public class House implements Room {
    Room[] rooms;

    public House() {
        rooms = new Room[]{new Parlor(), new Kitchen(), new Bedroom()};
    }


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

        for (Room part : rooms) {
            part.accept(visitor);
        }
    }
}

(4) 实现访问者类

public class Visitor {
    public void visit(House house) {
        System.out.println("好漂亮的房子!");
    }

    public void visit(Parlor parlor) {
        System.out.println("好宽敞的客厅!");
    }

    public void visit(Kitchen kitchen) {
        System.out.println("好整洁的厨房!");
    }

    public void visit(Bedroom bedroom) {
        System.out.println("好温馨的卧室!");
    }
}

(6) 使用访问者模式

public class VisitorDemo {
    public static void main(String[] args) {
        House house = new House();
        house.accept(new Visitor());
    }
}

运行结果:
image.png

3. 一些思考

访问者模式应该是23种经典设计模式中最难理解和掌握的了,SQL解析器中就大量的使用了访问者模式。

思考上述代码,我们看最后调用的方式:

house.accept(new Visitor());

可以这么来理解这行代码:house对象接受了一个访问者,这个访问者是Visitor类的一个实例

house就是主人的大房子,他可以允许客人来访问自己,但是是由主人来决定客人什么时候访问、怎么访问。这就是accept方法的实现。
visitor就是一个客人,它要访问主人的大房子,心里就必须先想好他要怎么访问。这就是visit方法的实现。

参考引用

访问者模式:www.runoob.com/design-patt…