访问者模式

《大话设计模式》阅读笔记和总结。原书是C#编写的,本人用Java实现了一遍,包括每种设计模式的UML图实现和示例代码实现。
目录:设计模式
Github地址:DesignPattern

说明

定义:访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

UML图:

访问者模式_第1张图片

代码实现:

Visitor类,为该对象结构中ConcreteElement的每一个类声明一个Visit操作

abstract class Visitor{
    public abstract void VisitConcreteElementA(ConcreteElementA elementA);
    public abstract void VisitConcreteElementB(ConcreteElementB elementB);
}

ConcreteVisitor1和ConcreteVisitor2类,具体访问者,实现每个由Visitor声明的操作。每个操作实现算法的一部分,而该算法片段是对应于结构中对象的类

class ConcreteVisitor1 extends Visitor {

    @Override
    public void VisitConcreteElementA(ConcreteElementA concreteElementA) {
        System.out.println(concreteElementA.getClass().getSimpleName() + "被"
                + this.getClass().getSimpleName() + "访问");
    }

    @Override
    public void VisitConcreteElementB(ConcreteElementB concreteElementB) {
        System.out.println(concreteElementB.getClass().getSimpleName() + "被"
                + this.getClass().getSimpleName() + "访问");
    }

}

class ConcreteVisitor2 extends Visitor {

    @Override
    public void VisitConcreteElementA(ConcreteElementA concreteElementA) {
        System.out.println(concreteElementA.getClass().getSimpleName() + "被"
                + this.getClass().getSimpleName() + "访问");
    }

    @Override
    public void VisitConcreteElementB(ConcreteElementB concreteElementB) {
        System.out.println(concreteElementB.getClass().getSimpleName() + "被"
                + this.getClass().getSimpleName() + "访问");
    }

}

Element类,定义一个Accept操作,它以一个访问者为参数

abstract class Element{
    public abstract void Accept(Visitor visitor);
}

ConcreteElementA和ConcreteElementB类,具体元素,实现Accept操作

class ConcreteElementA extends Element{

    @Override
    public void Accept(Visitor visitor) {
        visitor.VisitConcreteElementA(this);
    }

    public void OperationA(){

    }
}

class ConcreteElementB extends Element{

    @Override
    public void Accept(Visitor visitor) {
        visitor.VisitConcreteElementB(this);
    }

    public void OperationB(){

    }
}

ObjectStructure类,能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素

class ObjectStructure{
    private List elements = new ArrayList<>();
    public void Attach(Element element){
        elements.add(element);
    }
    public void Detach(Element element){
        elements.remove(element);
    }
    public void Accept(Visitor visitor){
        for (Element e :elements) {
            e.Accept(visitor);
        }
    }
}

客户端代码

public class VisitorPattern {
    public static void main(String[] args){
        ObjectStructure o = new ObjectStructure();
        o.Attach(new ConcreteElementA());
        o.Attach(new ConcreteElementB());

        ConcreteVisitor1 v1 = new ConcreteVisitor1();
        ConcreteVisitor2 v2 = new ConcreteVisitor2();

        o.Accept(v1);
        o.Accept(v2);
    }
}

运行结果

ConcreteElementA被ConcreteVisitor1访问
ConcreteElementB被ConcreteVisitor1访问
ConcreteElementA被ConcreteVisitor2访问
ConcreteElementB被ConcreteVisitor2访问

示例

例子:程序要求实现当男人和女人在不同状态下的反应。

男人成功时,背后多半有一个伟大的女人。
女人成功时,背后多半有一个伟大的男人。
男人失败时,闷头喝酒,谁也不用劝。
女人失败时,眼泪汪汪,谁也劝不了。
男人恋爱时,凡是不懂也要装懂。
女人恋爱时,遇事懂也装作不懂。
男女对比这么多的原因就是因为人类在性别上就只有男人和女人两类。

UML图:

访问者模式_第2张图片

代码实现:

抽象元素

public abstract class Person {
    public abstract void Accept(Action action);
}

男人

public class Man extends Person{

    @Override
    public void Accept(Action action) {
        action.GetManConclusion(this);
    }

}

女人

public class Woman extends Person{

    @Override
    public void Accept(Action action) {
        action.GetWomanConclusion(this);
    }

}

抽象状态类

public abstract class Action {
    public abstract void GetManConclusion(Person man);

    public abstract void GetWomanConclusion(Person woman);

}

成功状态

public class Success extends Action{

    @Override
    public void GetManConclusion(Person man) {
        System.out.println("男人成功时");
    }

    @Override
    public void GetWomanConclusion(Person woman) {
        System.out.println("女人成功时");
    }

}

失败状态

public class Failing extends Action{

    @Override
    public void GetManConclusion(Person man) {
        System.out.println("男人失败时");
    }

    @Override
    public void GetWomanConclusion(Person woman) {
        System.out.println("女人失败时");
    }

}

恋爱状态

public class Amativeness extends Action {

    @Override
    public void GetManConclusion(Person man) {
        System.out.println("男人恋爱时");
    }

    @Override
    public void GetWomanConclusion(Person woman) {
        System.out.println("女人恋爱时");
    }

}

结婚状态

public class Marriage extends Action{

    @Override
    public void GetManConclusion(Person man) {
        System.out.println("男人结婚时...");

    }

    @Override
    public void GetWomanConclusion(Person woman) {
        System.out.println("女人结婚时...");
    }

}

对象结构,用于访问男,女元素

public class PersonObjectStructure {
    //对象结构,用于访问男,女元素
    private List list = new ArrayList<>();

    public void Attach(Person person) {
        list.add(person);
    }

    public void Detach(Person person) {
        list.remove(person);
    }

    public void Display(Action action) {
        for (Person person : list) {
            person.Accept(action);
        }
    }

}

客户端代码

public class Main {
    public static void main(String[] args) {
        PersonObjectStructure objectStructure=new PersonObjectStructure();
        objectStructure.Attach(new Man());
        objectStructure.Attach(new Woman());

        //看男人和女人在成功时的状态
        Success success=new Success();
        objectStructure.Display(success);

        //新增一个结婚状态
        Marriage marriage=new Marriage();
        objectStructure.Display(marriage);
    }
}

运行结果

男人成功时
女人成功时
男人结婚时...
女人结婚时...

你可能感兴趣的:(编程)