每天一个设计模式之访问者模式(Visitor Pattern)

设计模式有23种之多,要想记住这二十多种模式的确不太容易,但是如果将模式的名字与典型的场景结合起来可能会更容易记忆。对于访问者模式,一个典型的例子就是不同的游客(visitor)游览一个地方不同的景区

访问者模式的意图是将易变的操作和稳定的数据结构分离开。文本典型的例子中,一个地方的景区基本上是稳定不变的,而对不同游客所做的优惠活动则会有很多不同的类型,比如学生游客,教师游客,老年游客,外国游客,抗疫志愿者游客等等。

一、UML类图

每天一个设计模式之访问者模式(Visitor Pattern)_第1张图片

二、代码示例

Visitor接口

public interface Visitor {
    void visitSummerPalace(SummerPalace summerPalace);
    void visitTheGreatWall(TheGreatWall theGreatWall);
}

Visitor具体类 - 学生visitor

public class StudentVisitor implements Visitor {
    @Override
    public void visitSummerPalace(SummerPalace summerPalace) {
        double v = summerPalace.ticketRate() * 0.5;
        System.out.println("half price to visit SummerPalace for students. # The price is $" + v);
    }

    @Override
    public void visitTheGreatWall(TheGreatWall theGreatWall) {
        double v = theGreatWall.ticketRate() * 0.5;
        System.out.println("half price to visit The Great Wall for students. # The price is $" + v);
    }
}

Visitor具体类 - 抗疫英雄visitor

public class FightCovidHeroVisitor implements Visitor {
    @Override
    public void visitSummerPalace(SummerPalace summerPalace) {
        double v = summerPalace.ticketRate() * 0.0;
        System.out.println("free to visit SummerPalace for fighting Convid-19 heroes. # The price is $" + v);
    }

    @Override
    public void visitTheGreatWall(TheGreatWall theGreatWall) {
        double v = theGreatWall.ticketRate() * 0.0;
        System.out.println("free to visit The Great Wall for fighting Convid-19 heroes. The price is $" + v);
    }
}


Element接口

public interface ScenerySpot {
    void accept(Visitor visitor);
    int ticketRate();
}

Element具体类 - 颐和园

public class SummerPalace implements ScenerySpot {

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

    @Override
    public int ticketRate() {
        return 120;
    }
}

Element具体类 - 长城

public class TheGreatWall implements ScenerySpot {

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

    @Override
    public int ticketRate() {
        return 100;
    }
}

Object Structure - 旅游管理中心

public class BeijingTourismCenter {
    private Set<ScenerySpot> scenerySpotSet = new HashSet<>();

    public void accept(Visitor visitor) {
        for (ScenerySpot spot : scenerySpotSet)
            spot.accept(visitor);
    }

    public void add(ScenerySpot spot) {
        scenerySpotSet.add(spot);
    }

    public void remove(ScenerySpot spot) {
        scenerySpotSet.remove(spot);
    }
}

客户类

public class Client {
    public static void main(String[] args) {
        BeijingTourismCenter tourismCenter = new BeijingTourismCenter();
        tourismCenter.add(new SummerPalace());
        tourismCenter.add(new TheGreatWall());
        // add more...

        tourismCenter.accept(new FightCovidHeroVisitor());
        System.out.println("----------------------------");
        tourismCenter.accept(new StudentVisitor());
        // accept more...
    }
}

运行结果

free to visit SummerPalace for fighting Convid-19 heroes. # The price is $0.0
free to visit The Great Wall for fighting Convid-19 heroes. The price is $0.0
----------------------------
half price to visit SummerPalace for students. # The price is $60.0
half price to visit The Great Wall for students. # The price is $50.0

Process finished with exit code 0

三、补充说明

访问者模式包含一个 Double dispatch (双分派)的概念。

spot.accept(visitor);

spot 是动态绑定的,visitor 也是动态绑定的。

四、参考

  1. https://www.runoob.com/design-pattern/visitor-pattern.html
  2. https://www.baeldung.com/java-visitor-pattern
  3. https://cloud.tencent.com/developer/article/1755832

设计模式系列博文导航

一、创建型 - 5种

原型模式(Prototype Pattern)
抽象工厂模式(Abstract Factory Pattern)
建造者模式(Builder Pattern)
工厂模式(Factory Pattern)
单例模式(Singleton Pattern)

助记语:原抽建工单

二、结构型 - 8种

享元模式(Flyweight Pattern)
代理模式(Proxy Pattern)
适配器模式(Adapter Pattern)
外观模式(Facade Pattern)

过滤器模式(Filter/Criteria Pattern)
桥接模式(Bridge Pattern)
组合模式(Composite Pattern)
装饰器模式(Decorator Pattern)

助记语:想呆室外,过桥组装

三、行为型 - 11种

责任链模式(Chain of Responsibility Pattern)
命令模式(Command Pattern)
解释器模式(Interpreter Pattern)
中介者模式(Mediator Pattern)
迭代器模式(Iterator Pattern)

观察者模式(Observer Pattern)
策略模式(Strategy Pattern)
状态模式(State Pattern)

备忘录模式(Memento Pattern)
模板方法模式(Template Pattern)
访问者模式(Visitor Pattern)

助记语:责令解中谍,观测状被模仿

你可能感兴趣的:(软件设计,访问者模式,设计模式,java)