持续创造,加快生长!这是我参与「日新方案 10 月更文挑战」的第7天,点击查看活动详情

拜访者形式

拜访者形式属于行为型形式。它是一种将数据结构与数据操作别离的规划形式。是指封装一些作用于某种数据结构中的各元素的操作,它能够在不改变数据结构的前提下界说作用于这些元素的新的操作。

拜访者形式被称为最复杂的规划形式,运用频率不高。

拜访者形式最大的优点便是添加拜访者非常容易,如果要添加一个拜访者,只需新完成一个拜访者接口的类,从而达到数据目标与数据操作相别离的效果。

应用

1.数据结构稳定,作用于数据结构的操作常常改变的场景
2.需求数据结构与数据操作别离的场景
3.需求对不同数据类型(元素)进行操作,而不运用分支判断详细类型的场景

举例:饭店吃饭,饭店菜品相对固定,但每天去吃饭的人是改变的,人即拜访者。

主要人物

1.笼统拜访者(Visitor)

接口或笼统类,界说了对每一个详细元素(Element)的拜访行为visit()办法,其参数便是详细的元素(Element)目标

一般来说:Visitor的办法个数与元素(Element)个数是持平的。如果元素(Element)个数常常改变,会导致Visitor的办法也要进行改变

2.详细拜访者(ConcreteVisitor)

完成对详细元素的操作

3.笼统元素(Element)

接口或笼统类,界说一个承受拜访者拜访的办法accept(),表明所有元素类型都支持被拜访者拜访

4.详细元素(Concrete Element)

详细元素类型,供给承受拜访者的详细完成。一般的完成都为:visitor.visit(this)

5.结构目标(ObjectStruture)

该类内部保护了元素调集,并供给办法承受拜访者对该调集所有元素进行操作

行为型设计模式之访问者模式

优缺点

优点:

1.解耦了数据结构与数据操作,使得操作调集能够独立改变
2.扩展性好:能够通过扩展拜访者人物,完成对数据集的不同操作
3.元素详细类型并非单一,拜访者均可操作
4.心各人物责任别离,符合单一责任原侧出前

缺点:

1.无法添加元素类型:若系统数据结构目标易于改变,常常有新的数据目标添加进来,则拜访者类有必要添加对应元素类型的操作,违反开闭准则
2.详细元素改变困难:详细元素添加属性,删去属性等操作会导致对应的拜访者类需求进行相应的修正,尤其当有大量拜访者类时,修正规模太大
3.违反依赖倒置准则:拜访者依赖的是详细元素类型,而不是笼统

根本运用

创立笼统拜访者

public interface IVisitor {
    void visit(ConcreteElementA element);
    void visit(ConcreteElementB element);
}

创立详细拜访者

public class ConcreteVisitorA implements IVisitor {
    public void visit(ConcreteElementA element) {
        String result = element.get();
        System.out.println("详细拜访者ConcreteVisitorA,拜访成果: " + result);
    }
    public void visit(ConcreteElementB element) {
        String result = element.get();
        System.out.println("详细拜访者ConcreteVisitorA,拜访成果: " + result);
    }
}
public class ConcreteVisitorB implements IVisitor {
    public void visit(ConcreteElementA element) {
        String result = element.get();
        System.out.println("详细拜访者ConcreteVisitorB,拜访成果: " + result);
    }
    public void visit(ConcreteElementB element) {
        String result = element.get();
        System.out.println("详细拜访者ConcreteVisitorB,拜访成果: " + result);
    }
}

创立笼统元素

public interface IElement {
    void accept(IVisitor visitor);
}

创立详细元素

public class ConcreteElementA implements IElement {
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }
    public String get() {
        return "我是详细元素ConcreteElementA";
    }
}
public class ConcreteElementB implements IElement {
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }
    public String get() {
      return "我是详细元素ConcreteElementB";
    }
}

创立结构目标

public class ObjectStructure {
    private List<IElement> list = new ArrayList<IElement>();
    {
        this.list.add(new ConcreteElementA());
        this.list.add(new ConcreteElementB());
    }
    public void accept(IVisitor visitor) {
        for (IElement element : this.list) {
            element.accept(visitor);
        }
    }
}

客户端履行

    public static void main(String[] args) {
        // 结构目标
        ObjectStructure collection = new ObjectStructure();
        // 拜访者A
        IVisitor visitorA = new ConcreteVisitorA();
        collection.accept(visitorA);
        System.out.println("------------------------------------");
        // 拜访者B
        IVisitor visitorB = new ConcreteVisitorB();
        collection.accept(visitorB);
    }
详细拜访者ConcreteVisitorA,拜访成果: 我是详细元素ConcreteElementA
详细拜访者ConcreteVisitorA,拜访成果: 我是详细元素ConcreteElementB
------------------------------------
详细拜访者ConcreteVisitorB,拜访成果: 我是详细元素ConcreteElementA
详细拜访者ConcreteVisitorB,拜访成果: 我是详细元素ConcreteElementB